package com.huawang.mdesign.model.service.inter;

import com.huawang.business.command.CommandAddType;
import com.huawang.business.command.CommandParameter;
import com.huawang.business.constants.ErrorCode;
import com.huawang.business.constants.ModelConstantURI;
import com.huawang.business.constants.ProjectTypeEnum;
import com.huawang.business.dto.ModelPropertyInfo;
import com.huawang.business.dto.ModifyPropertyDTO;
import com.huawang.business.dto.ProjectDTO;
import com.huawang.business.dto.UpdateModelDTO;
import com.huawang.business.dto.project.ModelDependency;
import com.huawang.business.dto.project.Project;
import com.huawang.business.exception.AbortExecutionException;
import com.huawang.business.service.encapsulation.EncapsulationService;
import com.huawang.business.service.encapsulation.IEncapsulationService;
import com.huawang.business.service.init.IInitializeService;
import com.huawang.business.service.model.base.*;
import com.huawang.business.service.model.core.InternalModelIconService;
import com.huawang.business.service.model.core.InternalUmlService;
import com.huawang.business.service.model.core.ModelPropertyInfoService;
import com.huawang.business.service.model.core.PasteSupplement;
import com.huawang.business.service.model.core.number.GlobalNumberCache;
import com.huawang.business.service.model.core.number.GlobalNumberGenerator;
import com.huawang.business.service.model.core.project.InternalProjectService;
import com.huawang.business.service.model.core.project.ProjectManager;
import com.huawang.business.service.model.core.property.PropertyManager;
import com.huawang.business.service.model.core.property.UpdateModelFactory;
import com.huawang.business.service.model.core.property.update.UpdateTriggerEventType;
import com.huawang.business.service.transaction.TransactionServiceImpl;
import com.huawang.business.util.InstanceVoUtils;
import com.huawang.business.util.ValidateDataUtil;
import com.huawang.business.vo.CopyInfoVo;
import com.huawang.business.vo.CopyResultVo;
import com.huawang.business.vo.RelationshipVo;
import com.huawang.core.definition.mof.UMLDefinitionConstants;
import com.huawang.core.definition.mof.cmof.reflection.RElement;
import com.huawang.core.definition.mof.cmof.reflection.impl.BasicRElement;
import com.huawang.core.definition.mof.instances.MetaClassInstance;
import com.huawang.core.definition.mof.util.SnowflakeIdWorkerUtil;
import com.huawang.core.mof.persistence.datasource.DataSourceRepository;
import com.huawang.core.semantics.constants.TypeEnum;
import com.huawang.core.semantics.entity.MofPropertyInfo;
import com.huawang.core.semantics.entity.queryResult.MofResultContainer;
import com.huawang.core.semantics.entity.queryResult.QueryPropertyForm;
import com.huawang.core.semantics.entity.transaction.LocalTransaction;
import com.huawang.core.semantics.exception.LocalTransactionNotStartException;
import com.huawang.core.semantics.exception.TransactionNotExistingException;
import com.huawang.mdesign.model.service.constant.DuplicateNameHandlingEnum;
import com.huawang.mdesign.model.service.constant.ModelPropertyOperationEnum;
import com.huawang.mdesign.model.service.constant.RefactoringModelReuseStrategy;
import com.huawang.mdesign.model.service.dto.CreateModelByLibraryDTO;
import com.huawang.mdesign.model.service.dto.ModelLibraryDropDTO;
import com.huawang.mdesign.model.service.dto.ProjectOpenDTO;
import com.huawang.mdesign.model.service.dto.modellibrary.*;
import com.huawang.mdesign.model.service.util.LogUtil;
import com.huawang.mdesign.model.service.util.uaf.ProjectUtils;
import com.huawang.mdesign.model.service.vo.LibraryCreateInstanceVo;
import com.huawang.mdesign.model.service.vo.ProjectVo;
import com.huawang.mdesign.model.service.vo.modellibrary.*;
import com.huawang.mdesign.model.service.vo.selectelementitem.SelectElementItem;
import com.huawang.mdesign.model.service.facade.dto.modellibrary.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.huawang.business.constants.ModelActionName.COPY_MODEL;
import static com.huawang.business.constants.ProfileConstants.DEFAULT_PROFILE;

@Service
@Primary
@Slf4j
public class ModelLibraryService {

    @Autowired
    private InternalUmlService internalUmlService;

    @Autowired
    private ProjectService projectService;

    @Autowired
    private UmlService umlService;

    @Autowired
    private ProjectManager projectManager;

    @Autowired
    private ModelPropertyInfoService modelPropertyInfoService;

    @Autowired
    private InternalProjectService internalProjectService;

    @Autowired
    private UpdateTriggerEventType updateTriggerEventType;

    @Autowired
    private TransactionServiceImpl transactionService;

    @Autowired
    private IInitializeService initializeService;

    @Autowired
    private ElementFindService elementFindService;

    @Autowired
    private ElementDefineService elementDefineService;

    @Autowired
    private RelationshipService relationshipService;

    @Autowired
    private PropertyManager propertyManager;

    @Autowired
    private GlobalNumberGenerator globalNumberGenerator;

    @Autowired
    private GlobalNumberCache globalNumberCache;

    @Autowired
    private InternalModelIconService internalModelIconService;

    @Autowired
    private IEncapsulationService encapsulationService;

    @Autowired
    private ModelService modelService;

    @Autowired
    private PasteSupplement pasteSupplement;

    @Autowired
    private ElementNameService elementNameService;

    @Autowired
    private ElementCheckService elementCheckService;


    private static final String ELEMENT_NAME = "elementName";
    private static final String VALUE_PROPERTY_EXIST = "valuePropertyExist";
    private static final String VALUE_PROPERTY_NUM = "valuePropertyNum";
    private static final String VALUE_PROPERTY_NAME_AND_DEFAULT_VALUE = "valuePropertyNameAndDefaultValue";
    private static final String PART_EXIST = "partExist";
    private static final String PART_NUM = "partNum";
    private static final String PORT_EXIST = "portExist";
    private static final String PORT_NUM = "portNum";
    private static final String NAME = "name";
    private static final String NUM = "num";
    private static final String DEFAULT_VALUE = "defaultValue";
    private static final String CUSTOMIZE = "customize";

    private static final String GT = ">";
    private static final String GE = ">=";
    private static final String LT = "<";
    private static final String LE = "<=";
    private static final String EQ = "==";

    private ClassifierBehaviorStrategy classifierBehaviorStrategy;

    private DuplicateNameHandlingStrategy duplicateNameHandlingStrategy;

    private static final Map<String, Boolean> BOOLEAN_MAP = new HashMap<>();

    static {
        BOOLEAN_MAP.put("true", true);
        BOOLEAN_MAP.put("false", false);
        BOOLEAN_MAP.put("1", true);
        BOOLEAN_MAP.put("0", false);
    }

    private static final Set<String> COMPUTED_PROPERTIES_NEED_COPY = Stream.of(
            UMLDefinitionConstants.NamedElement_satisfies,
            UMLDefinitionConstants.NamedElement_refines,
            UMLDefinitionConstants.NamedElement_verifies,
            UMLDefinitionConstants.NamedElement_allocatedTo,
            UMLDefinitionConstants.NamedElement_allocatedFrom,
            UMLDefinitionConstants.NamedElement_tracedFrom,
            UMLDefinitionConstants.SysML_AbstractRequirement_derived,
            UMLDefinitionConstants.SysML_AbstractRequirement_derivedFrom,
            UMLDefinitionConstants.SysML_AbstractRequirement_satisfiedBy,
            UMLDefinitionConstants.SysML_AbstractRequirement_refinedBy,
            UMLDefinitionConstants.SysML_AbstractRequirement_verifiedBy,
            UMLDefinitionConstants.SysML_AbstractRequirement_tracedTo,
            UMLDefinitionConstants.SysML_AbstractRequirement_master

    ).collect(Collectors.toSet());

    @NotNull
    public LibraryCreateInstanceVo createInstance(CreateModelByLibraryDTO dto) {
        LogUtil.printSerializeOnlineLogs("dto: ", dto);
        final String projectId = dto.getProjectId();
        final MetaClassInstance targetInstance = internalUmlService.fetchExistInstance(dto.getTargetInstanceId(), projectId);
        final MetaClassInstance modelLibraryInstance = internalUmlService.fetchExistInstance(dto.getModelLibraryInstanceId(),
                dto.getModelLibraryProjectId());

        String parentId = dto.getPackageId();
        if (StringUtils.isBlank(parentId)) {
            MetaClassInstance parent = queryParent(projectId, modelLibraryInstance, targetInstance);
            if (Objects.isNull(parent)) {
                throw AbortExecutionException.build(ErrorCode.PARENT_ERROR);
            }
            parentId = parent.getId();
        }
        LibraryCreateInstanceVo libraryCreateInstanceVo = new LibraryCreateInstanceVo();
        LocalTransaction transaction = transactionService.createTransaction(projectId, COPY_MODEL);
        try {
            Map<String, MetaClassInstance> result = umlService.paste(dto.getModelLibraryProjectId(),
                    dto.getModelLibraryInstanceId(), dto.getProjectId(), parentId);

            MetaClassInstance modelInstance = result.get(modelLibraryInstance.getId());
            if (Objects.isNull(modelInstance)) {
                throw AbortExecutionException.build(ErrorCode.ADD_MODEL_ERROR);
            }
            libraryCreateInstanceVo.setInstanceId(modelInstance.getId());
            // 填充复制粘贴模型 旧模型->新模型映射
            libraryCreateInstanceVo.setCopyInfoVos(getCopyInfoVo(result));

            MetaClassInstance firstInstance = result.get(dto.getModelLibraryInstanceId());
            this.updateTriggers(projectId, dto, modelLibraryInstance, firstInstance);
            globalNumberGenerator.pasteElementSetNumber(dto.getModelLibraryProjectId(), dto.getProjectId(),
                    modelLibraryInstance, result);

            // 模型库模型拖到视图模型内，更新模型属性
            if (StringUtils.isNotEmpty(dto.getInstanceId())) {
                ModifyPropertyDTO modifyPropertyDto = new ModifyPropertyDTO();
                modifyPropertyDto.setProjectId(projectId);
                modifyPropertyDto.setInstanceId(dto.getInstanceId());
                modifyPropertyDto.setKey(dto.getKey());
                modifyPropertyDto.setIsMultiplicity(dto.getIsMultiplicity());
                modifyPropertyDto.setDataType(dto.getDataType());
                modifyPropertyDto.setUpdateMethod(dto.getUpdateMethod());
                modifyPropertyDto.setValue(Collections.singletonList(modelInstance.getId()));
                propertyManager.updatePropertyValue(modifyPropertyDto);
            }

            transactionService.commit(projectId);
            InstanceVoUtils.fillModelResultVo(libraryCreateInstanceVo, transaction);
        } catch (TransactionNotExistingException | LocalTransactionNotStartException e) {
            throw AbortExecutionException.build(ErrorCode.TRANSACTION_ERROR, e);
        } catch (Exception e) {
            transactionService.rollBack(projectId, transaction);
            throw AbortExecutionException.build(ErrorCode.ADD_MODEL_ERROR, e);
        }
        return libraryCreateInstanceVo;
    }

    @NotNull
    public LibraryCreateInstanceVo createRelationshipInstance(CreateModelByLibraryDTO dto) {
        LogUtil.printSerializeOnlineLogs("dto: ", dto);
        final String projectId = dto.getProjectId();
        final MetaClassInstance targetInstance = internalUmlService.fetchExistInstance(dto.getTargetInstanceId(), projectId);
        final MetaClassInstance modelLibraryInstance = internalUmlService.fetchExistInstance(dto.getModelLibraryInstanceId(),
                dto.getModelLibraryProjectId());
        MetaClassInstance parent = queryParent(projectId, modelLibraryInstance, targetInstance);
        if (Objects.isNull(parent)) {
            throw AbortExecutionException.build(ErrorCode.PARENT_ERROR);
        }
        final RelationshipVo relationshipVo = relationshipService.fillRelationElement(dto.getModelLibraryProjectId(), modelLibraryInstance);

        LibraryCreateInstanceVo libraryCreateInstanceVo = new LibraryCreateInstanceVo();
        LocalTransaction transaction = transactionService.createTransaction(projectId, COPY_MODEL);
        try {
            Map<String, MetaClassInstance> result = umlService.pastes(dto.getModelLibraryProjectId(),
                    Arrays.asList(relationshipVo.getTargetId(), relationshipVo.getSourceId(), dto.getModelLibraryInstanceId()), dto.getProjectId(), parent.getId());

            MetaClassInstance modelInstance = result.get(modelLibraryInstance.getId());
            if (Objects.isNull(modelInstance)) {
                throw AbortExecutionException.build(ErrorCode.ADD_MODEL_ERROR);
            }
            libraryCreateInstanceVo.setInstanceId(modelInstance.getId());
            // 填充复制粘贴模型 旧模型->新模型映射
            libraryCreateInstanceVo.setCopyInfoVos(getCopyInfoVo(result));

            this.updateTriggers(projectId, dto, modelLibraryInstance, result.get(relationshipVo.getTargetId()));
            this.updateTriggers(projectId, dto, modelLibraryInstance, result.get(relationshipVo.getSourceId()));
            globalNumberGenerator.pasteElementSetNumber(dto.getModelLibraryProjectId(), dto.getProjectId(),
                    modelLibraryInstance, result);

            transactionService.commit(projectId);
            InstanceVoUtils.fillModelResultVo(libraryCreateInstanceVo, transaction);
        } catch (TransactionNotExistingException | LocalTransactionNotStartException e) {
            throw AbortExecutionException.build(ErrorCode.TRANSACTION_ERROR, e);
        } catch (Exception e) {
            transactionService.rollBack(projectId, transaction);
            throw AbortExecutionException.build(ErrorCode.ADD_MODEL_ERROR, e);
        }
        return libraryCreateInstanceVo;
    }

    public boolean checkAppliedStereotype(ModelLibraryDropDTO dto) {
        final MetaClassInstance modelLibraryInstance = internalUmlService.fetchExistInstance(dto.getModelLibraryInstanceId(),
                dto.getModelLibraryProjectId());
        List<MetaClassInstance> childrenCascade = internalUmlService.getChildrenCascade(dto.getProjectId(), modelLibraryInstance, true);
        List<MetaClassInstance> metaClassInstances = internalUmlService.queryProperty(dto.getModelLibraryProjectId(), childrenCascade, UMLDefinitionConstants.Element_appliedStereotype);

        Set<String> instanceIds = metaClassInstances.stream().map(MetaClassInstance::getId).collect(Collectors.toSet());

        List<MetaClassInstance> metaClassInstances1 = internalUmlService.fetchInstanceByIds(new ArrayList<>(instanceIds), dto.getProjectId());
        return instanceIds.size() == metaClassInstances1.size();
    }

    private static List<RefactorCopyInfo> getRefactorCopyInfo(String projectId, Map<String, Map<String, MetaClassInstance>> batchReconstructionMap,
                                                              Map<String, List<ModelMappingInfo>> modelMappingInfoMap, int reuseStrategy) {
        List<RefactorCopyInfo> list = new ArrayList<>();

        // 填充复制粘贴模型 旧模型->新模型映射
        batchReconstructionMap.forEach((instanceId, reconstructionMap) -> {
            RefactorCopyInfo refactorCopyInfo = new RefactorCopyInfo();
            refactorCopyInfo.setTargetInstanceId(instanceId);
            String oldProjectId = getModelOldProjectId(projectId, modelMappingInfoMap, instanceId, reuseStrategy, reconstructionMap);
            List<RefactorMapping> refactorMappings = new ArrayList<>();
            reconstructionMap.forEach((oldInstanceId, newInstance) -> {
                RefactorMapping refactorMapping = new RefactorMapping();
                refactorMapping.setOldId(oldInstanceId);
                refactorMapping.setOldProjectId(oldProjectId);
                refactorMapping.setNewId(newInstance.getId());
                refactorMappings.add(refactorMapping);
            });
            refactorCopyInfo.setRefactorMappings(refactorMappings);
            list.add(refactorCopyInfo);
        });
        return list;
    }

    private static String getModelOldProjectId(String projectId, Map<String, List<ModelMappingInfo>> modelMappingInfoMap,
                                               String id, int reuseStrategy, Map<String, MetaClassInstance> reconstructionMap) {
        for (Map.Entry<String, List<ModelMappingInfo>> entry : modelMappingInfoMap.entrySet()) {
            List<ModelMappingInfo> value = entry.getValue();
            Set<String> instanceIds = value.stream().map(ModelMappingInfo::getInstanceId).collect(Collectors.toSet());
            String valueId = id;
            if (reuseStrategy == 2) {
                for (Map.Entry<String, MetaClassInstance> entry1 : reconstructionMap.entrySet()) {
                    String key = entry1.getKey();
                    MetaClassInstance instance = entry1.getValue();
                    if (StringUtils.equals(instance.getId(), id)) {
                        valueId = key;
                        break;
                    }
                }
                instanceIds = value.stream().map(ModelMappingInfo::getModelLibraryInstanceId).collect(Collectors.toSet());
            }
            if (instanceIds.contains(valueId)) {
                return entry.getKey();
            }
        }
        return projectId;
    }

    private static List<CopyInfoVo> getCopyInfoVo(Map<String, MetaClassInstance> result) {
        List<CopyInfoVo> list = new ArrayList<>();
        // 填充复制粘贴模型 旧模型->新模型映射
        result.forEach((oldInstanceId, newInstance) -> {
            CopyInfoVo copyInfoVo = new CopyInfoVo();
            copyInfoVo.setOldId(oldInstanceId);
            copyInfoVo.setNewId(newInstance.getId());
            list.add(copyInfoVo);
        });
        return list;
    }


    private void updateTriggers(@NotNull final String projectId,
                                @NotNull final CreateModelByLibraryDTO dto,
                                @NotNull final MetaClassInstance modelLibraryInstance,
                                @Nullable final MetaClassInstance firstInstance) {
        LogUtil.printSerializeOnlineLogs("projectId: {}, dto: {}, modelLibraryInstance: {}, firstInstance: {}",
                projectId, dto, modelLibraryInstance, firstInstance);
        if (firstInstance != null) {
            umlService.rename(projectId, firstInstance);
            // 如果是等待时间动作，为其触发器设置事件类型，否则它只是一个接受事件动作
            if (internalUmlService.checkInstanceType(dto.getModelLibraryProjectId(), modelLibraryInstance,
                    UMLDefinitionConstants.AcceptEventAction)) {
                List<MetaClassInstance> triggerList = internalUmlService.queryListInstanceProperty(dto.getModelLibraryProjectId(),
                        modelLibraryInstance, UMLDefinitionConstants.AcceptEventAction_trigger);
                if (CollectionUtils.isNotEmpty(triggerList)) {
                    MetaClassInstance eventType = internalUmlService.queryInstanceProperty(dto.getModelLibraryProjectId(),
                            triggerList.get(0), UMLDefinitionConstants.Trigger_eventType);
                    if (Objects.nonNull(eventType)) {
                        List<MetaClassInstance> triggers = internalUmlService.queryListInstanceProperty(projectId,
                                firstInstance, UMLDefinitionConstants.AcceptEventAction_trigger);
                        if (CollectionUtils.isNotEmpty(triggers)) {
                            ModifyPropertyDTO modifyPropertyDto = new ModifyPropertyDTO();
                            modifyPropertyDto.setProjectId(projectId);
                            modifyPropertyDto.setInstanceId(triggers.get(0).getId());
                            modifyPropertyDto.setValue(Collections.singletonList(eventType.getId()));
                            updateTriggerEventType.updateTriggerEventType(modifyPropertyDto);
                        }
                    }
                }
            }
        }
    }


    /**
     * 通过模型库创建模型查询模型的parent
     *
     * @param projectId
     * @param instance
     * @param targetInstance
     * @return com.huawang.model.instances.MetaClassInstance
     * @author baibf
     * @date 2023/03/31 17:27
     */
    @Nullable
    private MetaClassInstance queryParent(@NotNull final String projectId,
                                          @NotNull final MetaClassInstance instance,
                                          @NotNull final MetaClassInstance targetInstance) {
        LogUtil.printSerializeOnlineLogs("projectId: {}, instance: {}, targetInstance: {}", projectId, instance,
                targetInstance);
        MetaClassInstance parent = targetInstance;
        if (internalUmlService.checkInstanceType(projectId, targetInstance, UMLDefinitionConstants.SysMLStateMachineDiagram)) {
            String ownerId = targetInstance.getOwnerId();
            MetaClassInstance owner = this.internalUmlService.fetchInstance(ownerId, projectId);
            if (Objects.isNull(owner)) {
                log.error("{}的没有父节点", parent.getId());
                throw AbortExecutionException.build(ErrorCode.PARENT_ERROR);
            }
            List<MetaClassInstance> regions = internalUmlService.queryListInstanceProperty(projectId, owner,
                    UMLDefinitionConstants.StateMachine_region);
            if (CollectionUtils.isEmpty(regions)) {
                log.error("{}的StateMachine-region属性为空", parent.getId());
                throw AbortExecutionException.build(ErrorCode.PARENT_ERROR);
            }
            parent = regions.get(0);
        }
        List<String> ancestorIds = this.internalUmlService.getAncestorIds(projectId, parent, false);
        List<String> canSetType = this.elementDefineService.queryAllPossibleOwnerType(projectId,
                instance.getClassifier().getName());
        Map<String, MetaClassInstance> possibleOwnerInstancesMap = this.elementFindService.
                queryInstanceByInstanceIdsAndClassifierIds(projectId, ancestorIds, canSetType)
                .stream().collect(Collectors.toMap(RElement::getId, it -> it, (a, b) -> a));
        for (String ancestorId : ancestorIds) {
            // 寻找最近的owner作为parent
            if (possibleOwnerInstancesMap.containsKey(ancestorId)) {
                return possibleOwnerInstancesMap.get(ancestorId);
            }
        }
        log.warn("parent owner为根节点, 模型id:{}", parent.getId());
        throw AbortExecutionException.build(ErrorCode.PARENT_ERROR);
    }

    @Nullable
    public ProjectVo importLibrary(ProjectOpenDTO md3Dto) {
        LogUtil.printSerializeOnlineLogs("md3Dto", md3Dto);
        ProjectDTO projectDto = projectService.makeProjectDto(md3Dto);
        final String projectId = projectDto.getProjectId();
        final String rootId = projectDto.getRootModel();
        String currentId = SnowflakeIdWorkerUtil.getId();
        Project project = projectManager.getProject(projectId);
        if (project != null) {
            project.setRootModel(rootId);
            return projectService.makeVo(project);
        }

        projectManager.extractDb(projectDto.getFilePath(), currentId + "_" + projectId, md3Dto.getDefaultSaveDir());
        ValidateDataUtil.isNotNull(rootId);
        project = projectManager.createAndActive(projectId,
                projectDto.getDependencies(), currentId, md3Dto.getDefaultSaveDir(), projectDto.getProjectVersion(), ProjectUtils.getProjectSpecificationByProjectDTO(projectDto));
        project.setExport(projectDto.isExport());
        project.setProjectType(ProjectTypeEnum.MODEL_LIBRARY_IMPORTED.value());
        MetaClassInstance rootModelInstance;
        List<String> oldDefaultProfile = new ArrayList<>(DEFAULT_PROFILE);
        try {
            ProjectUtils.updateProfileByProjectSpecification(project.getProjectSpecification());
            project.setRootModel(rootId);
            final List<ModelDependency> dependencies = projectDto.getDependencies();
            final String profilePath = projectDto.getProfileLibPath();
            final List<ModelDependency> initProfile = DEFAULT_PROFILE.stream().map(it ->
                    new ModelDependency(it, 1L)
            ).collect(Collectors.toList());
            Set<String> profileIds = projectService.initProfileDependency(dependencies,
                    profilePath, initProfile, md3Dto.getProfileLibPath(), project);
            profileIds.addAll(initProfile.stream().map(ModelDependency::getProfileName).collect(Collectors.toList()));
            rootModelInstance = internalUmlService.fetchInstance(rootId, projectId);
            this.initializeService.initialize(projectId, false, true, true, project.getProjectSpecification());
            internalProjectService.setProfileOwner(project, rootModelInstance, profileIds);
            // 缓存项目中的编号属性
            globalNumberCache.putNumberProperties(projectId);
        } catch (Exception e) {
            ProjectUtils.rollBackDefaultProfile(oldDefaultProfile);
            projectManager.clear(projectId, md3Dto.getSaveWay());
            throw AbortExecutionException.build(ErrorCode.MODEL_LIBRARY_OPEN_ERROR, e);
        }

        return projectService.makeVo(project);
    }

    public RefactoringSchemeDefinitionVO obtainRefactoringSchemeDefinition(RefactoringSchemeDefinitionDTO refactoringSchemeDefinitionDTO) {
        classifierBehaviorStrategy = refactoringSchemeDefinitionDTO.getClassifierBehaviorStrategy();
        duplicateNameHandlingStrategy = refactoringSchemeDefinitionDTO.getNamingStrategy();

        String projectId = refactoringSchemeDefinitionDTO.getProjectId();
        String instanceId = refactoringSchemeDefinitionDTO.getInstanceId();
        String refactoringScope = refactoringSchemeDefinitionDTO.getRefactoringScope();
        List<String> modelLibraryProjectIds = refactoringSchemeDefinitionDTO.getReferenceModelLibrary();
        List<ConditionalSet> conditionalConstraints = refactoringSchemeDefinitionDTO.getConditionalConstraints();
        RecommendedPriority recommendedPriority = refactoringSchemeDefinitionDTO.getRecommendedPriority();
        // 模型库中的所有Block
        Map<String, List<MetaClassInstance>> blockMap = modelLibraryProjectIds.stream().collect(Collectors.toMap(it -> it,
                it1 -> internalUmlService.querySpecifiedInstanceList(it1, UMLDefinitionConstants.SysML_Block, false),
                (k, v) -> k));
        RefactoringSchemeDefinitionVO refactoringSchemeDefinitionVO = new RefactoringSchemeDefinitionVO();
        if (blockMap.isEmpty()) {
            return refactoringSchemeDefinitionVO;
        }
        List<ModelLibraryElementInfo> modelLibraryElementInfoList = new ArrayList<>();
        // 模块及其下的Property的信息
        blockMap.forEach((mlProjectId, instances) -> {
            QueryPropertyForm queryBlockForm = internalUmlService.getQueryPropertyForm(instances,
                    Stream.of(UMLDefinitionConstants.NamedElement_name,
                            UMLDefinitionConstants.Class_ownedAttribute).collect(Collectors.toList()));
            MofResultContainer blockContainer = internalUmlService.queryProperty(mlProjectId, queryBlockForm);
            List<MetaClassInstance> allAttributes = instances.stream().flatMap(it ->
                    blockContainer.queryListInstanceProperty(it.getId(), UMLDefinitionConstants.Class_ownedAttribute).stream())
                    .filter(Objects::nonNull).collect(Collectors.toList());
            List<MetaClassInstance> allDefaultValue = new ArrayList<>();
            ModelLibraryElementInfo modelLibraryElementInfo = new ModelLibraryElementInfo();
            modelLibraryElementInfo.setMlProjectId(mlProjectId);
            modelLibraryElementInfo.setInstanceIds(instances.stream().map(BasicRElement::getId).collect(Collectors.toList()));
            modelLibraryElementInfo.setBlockContainer(blockContainer);
            if (CollectionUtils.isNotEmpty(allAttributes)) {
                QueryPropertyForm queryAttributeForm = internalUmlService.getQueryPropertyForm(allAttributes,
                        Stream.of(UMLDefinitionConstants.NamedElement_name,
                                UMLDefinitionConstants.Property_defaultValue).collect(Collectors.toList()));
                MofResultContainer attributeContainer = internalUmlService.queryProperty(mlProjectId, queryAttributeForm);
                allDefaultValue = allAttributes.stream().map(it ->
                        attributeContainer.queryInstanceProperty(it.getId(),
                                UMLDefinitionConstants.Property_defaultValue)).filter(Objects::nonNull).collect(Collectors.toList());
                modelLibraryElementInfo.setAttributeContainer(attributeContainer);
            }
            if (CollectionUtils.isNotEmpty(allDefaultValue)) {
                QueryPropertyForm queryValueForm = internalUmlService.getQueryPropertyForm(allDefaultValue,
                        Stream.of(UMLDefinitionConstants.LiteralReal_value, UMLDefinitionConstants.LiteralInteger_value,
                                UMLDefinitionConstants.LiteralBoolean_value, UMLDefinitionConstants.LiteralString_value)
                                .collect(Collectors.toList()));
                MofResultContainer valueContainer = internalUmlService.queryProperty(mlProjectId, queryValueForm);
                modelLibraryElementInfo.setValueContainer(valueContainer);
            }

            Map<String, String> modelLibraryIconMap = modelPropertyInfoService.queryIconBatch(mlProjectId, instances);
            modelLibraryElementInfo.setMlIconMap(modelLibraryIconMap);
            modelLibraryElementInfoList.add(modelLibraryElementInfo);
        });

        List<ModelLibraryElementInfo> conformsConstraintElements = new ArrayList<>();
        List<ModelLibraryElementInfo> notComplyConstraintElements = new ArrayList<>();
        // 约束条件为空时，全部按符合处理
        if (CollectionUtils.isEmpty(conditionalConstraints)) {
            conformsConstraintElements.addAll(modelLibraryElementInfoList);
        } else {
            Pair<List<ModelLibraryElementInfo>, List<ModelLibraryElementInfo>> constraintElementPair =
                    constraintElementCalculation(modelLibraryElementInfoList, conditionalConstraints);
            conformsConstraintElements = constraintElementPair.getLeft();
            notComplyConstraintElements = constraintElementPair.getRight();
        }
        Map<String, Double> recommendedPriorityMap = recommendedPriorityHandle(recommendedPriority);

        Set<String> instanceIds = new HashSet<>();
        // 默认情况下展开的层级显示
        if (StringUtils.isEmpty(instanceId)) {
            MetaClassInstance currentInstance = internalUmlService.fetchInstance(refactoringScope, projectId);
            SelectElementItem selectElementItem = new SelectElementItem();
            selectElementItem.setInstanceId(refactoringScope);
            selectElementItem.setName(internalUmlService.queryStringProperty(projectId, currentInstance,
                    UMLDefinitionConstants.NamedElement_name));
            selectElementItem.setIcon(internalModelIconService.queryIcon(projectId, currentInstance));
            refactoringSchemeDefinitionVO.setOriginalElement(selectElementItem);

            refactoringSchemeDefinitionVO.setAdaptiveElement(buildAdaptiveElement(projectId, currentInstance,
                    conformsConstraintElements, notComplyConstraintElements, recommendedPriorityMap));
            instanceIds.add(refactoringScope);
            refactoringSchemeDefinitionVO.setChildNodeInfos(getChildNode(projectId, currentInstance, instanceIds, 2,
                    conformsConstraintElements, notComplyConstraintElements, recommendedPriorityMap));
            return refactoringSchemeDefinitionVO;
        }
        // 懒加载情况下展开具体模型
        MetaClassInstance selectInstance = internalUmlService.fetchInstance(instanceId, projectId);
        refactoringSchemeDefinitionVO.setChildNodeInfos(getChildNode(projectId, selectInstance, instanceIds, 1,
                conformsConstraintElements, notComplyConstraintElements, recommendedPriorityMap));
        return refactoringSchemeDefinitionVO;
    }

    public RefactoringElementPreviewVO refactoringElementPreview(RefactoringElementPreviewDTO refactoringElementPreviewDTO) {
        String projectId = refactoringElementPreviewDTO.getProjectId();
        String instanceId = refactoringElementPreviewDTO.getInstanceId();
        String modelLibraryProjectId = refactoringElementPreviewDTO.getModelLibraryProjectId();
        String modelLibraryInstanceId = refactoringElementPreviewDTO.getModelLibraryInstanceId();
        Integer reuseStrategy = refactoringElementPreviewDTO.getReuseStrategy();

        MetaClassInstance modelLibraryInstance = internalUmlService.fetchInstance(modelLibraryInstanceId, modelLibraryProjectId);
        QueryPropertyForm queryModelLibraryPropertyForm = internalUmlService.getQueryPropertyForm(modelLibraryInstance,
                Stream.of(UMLDefinitionConstants.BehavioredClassifier_classifierBehavior,
                        UMLDefinitionConstants.Class_ownedAttribute,
                        UMLDefinitionConstants.Class_nestedClassifier).collect(Collectors.toList()));
        MofResultContainer modelLibraryInstanceContainer = internalUmlService.queryProperty(modelLibraryProjectId, queryModelLibraryPropertyForm);
        MetaClassInstance modelLibraryClassifierBehavior = modelLibraryInstanceContainer.queryInstanceProperty(modelLibraryInstanceId,
                UMLDefinitionConstants.BehavioredClassifier_classifierBehavior);
        List<MetaClassInstance> modelLibraryInstanceList = new ArrayList<>();
        List<MetaClassInstance> modelLibraryOwnedDiagrams = new ArrayList<>();
        if (Objects.nonNull(modelLibraryClassifierBehavior)) {
            modelLibraryOwnedDiagrams = internalUmlService.queryListInstanceProperty(modelLibraryProjectId,
                    modelLibraryClassifierBehavior, UMLDefinitionConstants.Namespace_ownedDiagram);
            modelLibraryInstanceList.add(modelLibraryClassifierBehavior);
        }

        List<MetaClassInstance> modelLibraryOwnedAttributes = modelLibraryInstanceContainer.queryListInstanceProperty(modelLibraryInstanceId,
                UMLDefinitionConstants.Class_ownedAttribute);
        modelLibraryInstanceList.addAll(modelLibraryOwnedAttributes);
        List<MetaClassInstance> modelLibraryNestedClassifiers = modelLibraryInstanceContainer.queryListInstanceProperty(modelLibraryInstanceId,
                UMLDefinitionConstants.Class_nestedClassifier);
        modelLibraryInstanceList.addAll(modelLibraryNestedClassifiers);
        RefactoringElementPreviewVO refactoringElementPreviewVO = new RefactoringElementPreviewVO();
        QueryPropertyForm queryModelLibraryNameForm = internalUmlService.getQueryPropertyForm(modelLibraryInstanceList, UMLDefinitionConstants.NamedElement_name);
        MofResultContainer modelLibraryNameContainer = internalUmlService.queryProperty(modelLibraryProjectId, queryModelLibraryNameForm);
        Map<String, String> modelLibraryIconMap = modelPropertyInfoService.queryIconBatch(modelLibraryProjectId, modelLibraryInstanceList);

        List<SelectElementItem> partList = new ArrayList<>();
        List<SelectElementItem> parameterList = new ArrayList<>();
        List<SelectElementItem> portList = new ArrayList<>();
        classifyAttribute(projectId, modelLibraryOwnedAttributes, partList, portList, parameterList,
                modelLibraryNameContainer, modelLibraryIconMap);

        List<SelectElementItem> nestedClassifierList = modelLibraryNestedClassifiers.stream().map(it -> {
            String nestedClassifierId = it.getId();
            SelectElementItem selectElementItem = new SelectElementItem();
            selectElementItem.setInstanceId(nestedClassifierId);
            selectElementItem.setName(modelLibraryNameContainer.queryStringProperty(nestedClassifierId, UMLDefinitionConstants.NamedElement_name));
            selectElementItem.setIcon(modelLibraryIconMap.get(nestedClassifierId));
            return selectElementItem;
        }).collect(Collectors.toList());

        MetaClassInstance instance = internalUmlService.fetchInstance(instanceId, projectId);
        QueryPropertyForm queryPropertyForm = internalUmlService.getQueryPropertyForm(instance,
                Stream.of(UMLDefinitionConstants.BehavioredClassifier_classifierBehavior,
                        UMLDefinitionConstants.Class_ownedAttribute,
                        UMLDefinitionConstants.Class_nestedClassifier).collect(Collectors.toList()));
        MofResultContainer instanceContainer = internalUmlService.queryProperty(projectId, queryPropertyForm);
        MetaClassInstance classifierBehavior = instanceContainer.queryInstanceProperty(instanceId,
                UMLDefinitionConstants.BehavioredClassifier_classifierBehavior);
        List<MetaClassInstance> instanceList = new ArrayList<>();
        List<MetaClassInstance> ownedDiagrams = new ArrayList<>();
        if (Objects.nonNull(classifierBehavior)) {
            ownedDiagrams = internalUmlService.queryListInstanceProperty(projectId, classifierBehavior,
                    UMLDefinitionConstants.Namespace_ownedDiagram);
            instanceList.add(classifierBehavior);
        }

        List<MetaClassInstance> ownedAttributes = instanceContainer.queryListInstanceProperty(instanceId,
                UMLDefinitionConstants.Class_ownedAttribute);
        instanceList.addAll(ownedAttributes);
        List<MetaClassInstance> nestedClassifiers = instanceContainer.queryListInstanceProperty(instanceId,
                UMLDefinitionConstants.Class_nestedClassifier);
        instanceList.addAll(nestedClassifiers);

        QueryPropertyForm queryNameForm = internalUmlService.getQueryPropertyForm(instanceList, UMLDefinitionConstants.NamedElement_name);
        MofResultContainer nameContainer = internalUmlService.queryProperty(projectId, queryNameForm);
        Map<String, String> iconMap = modelPropertyInfoService.queryIconBatch(projectId, instanceList);

        Boolean classifierBehaviorReplace = classifierBehaviorStrategy.getClassifierBehaviorReplace();
        if (BooleanUtils.isTrue(classifierBehaviorReplace) && Objects.nonNull(modelLibraryClassifierBehavior)) {
            SelectElementItem classifierBehaviorSelectElement = new SelectElementItem();
            String classifierBehaviorId = modelLibraryClassifierBehavior.getId();
            classifierBehaviorSelectElement.setInstanceId(classifierBehaviorId);
            classifierBehaviorSelectElement.setName(modelLibraryNameContainer.queryStringProperty(classifierBehaviorId, UMLDefinitionConstants.NamedElement_name));
            classifierBehaviorSelectElement.setIcon(modelLibraryIconMap.get(classifierBehaviorId));
            refactoringElementPreviewVO.setClassifierBehavior(classifierBehaviorSelectElement);
            if (CollectionUtils.isNotEmpty(modelLibraryOwnedDiagrams)) {
                refactoringElementPreviewVO.setBehaviorDiagramId(modelLibraryOwnedDiagrams.get(0).getId());
                refactoringElementPreviewVO.setBehaviorDiagramProjectId(modelLibraryProjectId);
            }
        } else {
            if (Objects.nonNull(classifierBehavior) && Objects.equals(reuseStrategy, RefactoringModelReuseStrategy.RETAIN_STRUCTURAL_DEFINITION.getCode())) {
                SelectElementItem classifierBehaviorSelectElement = new SelectElementItem();
                String classifierBehaviorId = classifierBehavior.getId();
                classifierBehaviorSelectElement.setInstanceId(classifierBehaviorId);
                classifierBehaviorSelectElement.setName(nameContainer.queryStringProperty(classifierBehaviorId, UMLDefinitionConstants.NamedElement_name));
                classifierBehaviorSelectElement.setIcon(iconMap.get(classifierBehaviorId));
                refactoringElementPreviewVO.setClassifierBehavior(classifierBehaviorSelectElement);
                if (CollectionUtils.isNotEmpty(ownedDiagrams)) {
                    refactoringElementPreviewVO.setBehaviorDiagramId(ownedDiagrams.get(0).getId());
                    refactoringElementPreviewVO.setBehaviorDiagramProjectId(projectId);
                }
            }
        }

        // 全部替换的情况
        if (Objects.equals(reuseStrategy, RefactoringModelReuseStrategy.REPLACE_ALL.getCode())) {
            refactoringElementPreviewVO.setParts(partList);
            refactoringElementPreviewVO.setParameters(parameterList);
            refactoringElementPreviewVO.setPorts(portList);
            refactoringElementPreviewVO.setNestedClassifiers(nestedClassifierList);
            return refactoringElementPreviewVO;
        }

        // 保留结构及定义的情况
        classifyAttribute(projectId, ownedAttributes, partList, portList, parameterList, nameContainer, iconMap);

        refactoringElementPreviewVO.setParts(partList);
        refactoringElementPreviewVO.setParameters(parameterList);
        refactoringElementPreviewVO.setPorts(portList);

        nestedClassifierList.addAll(nestedClassifiers.stream().map(it -> {
            String nestedClassifierId = it.getId();
            SelectElementItem selectElementItem = new SelectElementItem();
            selectElementItem.setInstanceId(nestedClassifierId);
            selectElementItem.setName(nameContainer.queryStringProperty(nestedClassifierId, UMLDefinitionConstants.NamedElement_name));
            selectElementItem.setIcon(iconMap.get(nestedClassifierId));
            return selectElementItem;
        }).collect(Collectors.toList()));
        refactoringElementPreviewVO.setNestedClassifiers(nestedClassifierList);

        return refactoringElementPreviewVO;
    }

    public SchemeBasedReconstructionVO schemeBasedReconstruction(SchemeBasedReconstructionDTO schemeBasedReconstructionDTO) {
        SchemeBasedReconstructionVO schemeBasedReconstructionVO = new SchemeBasedReconstructionVO();
        String projectId = schemeBasedReconstructionDTO.getProjectId();
        String generateLocation = schemeBasedReconstructionDTO.getGenerateLocation();
        Boolean isMultiScheme = schemeBasedReconstructionDTO.getIsMultiScheme();
        List<RefactoringSchemeInfo> refactoringSchemeInfos = schemeBasedReconstructionDTO.getRefactoringSchemeInfos();
        List<TargetCopyInfoVo> targetCopyInfoVos = new ArrayList<>();
        List<BatchRefactoringModelDTO> batchRefactoringModelDTOList = new ArrayList<>();
        LocalTransaction transaction = transactionService.createTransaction(projectId, COPY_MODEL);
        try {
            if (isMultiScheme) {
                Map<String, List<ModelMappingInfo>> modelMappingInfoMaps = new HashMap<>();
                refactoringSchemeInfos.forEach(refactoringSchemeInfo -> {
                    Map<String, List<ModelMappingInfo>> modelMappingInfoMap = new HashMap<>();
                    BatchRefactoringModelDTO batchRefactoringModelDTO = new BatchRefactoringModelDTO();
                    batchRefactoringModelDTO.setProjectId(projectId);
                    batchRefactoringModelDTO.setClassifierBehaviorStrategy(classifierBehaviorStrategy);
                    batchRefactoringModelDTO.setNamingStrategy(duplicateNameHandlingStrategy);
                    batchRefactoringModelDTO.setReuseStrategy(schemeBasedReconstructionDTO.getReuseStrategy());
                    String schemeName = refactoringSchemeInfo.getSchemeName();
                    String packageId = ModelConstantURI.initInstanceId();
                    // 根据方案名称创建包
                    String defaultName = elementNameService.fetchDefaultName(projectId, UMLDefinitionConstants.Package,
                            generateLocation, schemeName, null);
                    final CommandParameter packageParameter = CommandParameter.builder()
                            .projectId(projectId)
                            .type(CommandAddType.MODEL)
                            .typeId(UMLDefinitionConstants.Package)
                            .parentId(generateLocation)
                            .instanceId(packageId)
                            .defaultName(defaultName)
                            .build();
                    umlService.addModel(packageParameter);

                    List<RefactoringSchemeDefinition> refactoringSchemeDefinitions = refactoringSchemeInfo.getRefactoringSchemeDefinitions();
                    List<String> instanceIds = refactoringSchemeDefinitions.stream().map(RefactoringSchemeDefinition::getInstanceId).collect(Collectors.toList());

                    Map<String, MetaClassInstance> newInstanceMap = new HashMap<>();
                    // 粘贴被复制的模型
                    instanceIds.forEach(instanceId -> {
                        Map<String, MetaClassInstance> result = umlService.paste(projectId, instanceId, projectId, packageId);
                        newInstanceMap.putAll(result);
                    });
                    List<CopyInfoVo> copyInfoVos = getCopyInfoVo(newInstanceMap);
                    TargetCopyInfoVo targetCopyInfoVo = new TargetCopyInfoVo();
                    targetCopyInfoVo.setCopyMappings(copyInfoVos);
                    targetCopyInfoVos.add(targetCopyInfoVo);
                    Map<String, List<RefactoringSchemeDefinition>> refactoringSchemeDefinitionMap = refactoringSchemeDefinitions.stream()
                            .collect(Collectors.groupingBy(RefactoringSchemeDefinition::getModelLibraryProjectId));
                    refactoringSchemeDefinitionMap.forEach((mlProjectId, value) -> {
                        List<ModelMappingInfo> modelMappingInfoList = value.stream().map(it -> {
                            ModelMappingInfo modelMappingInfo = new ModelMappingInfo();
                            // 重构的是粘贴出来模型
                            modelMappingInfo.setInstanceId(newInstanceMap.get(it.getInstanceId()).getId());
                            modelMappingInfo.setModelLibraryInstanceId(it.getModelLibraryInstanceId());
                            return modelMappingInfo;
                        }).collect(Collectors.toList());
                        modelMappingInfoMap.put(mlProjectId, modelMappingInfoList);
                        if (modelMappingInfoMaps.containsKey(mlProjectId)) {
                            modelMappingInfoMaps.get(mlProjectId).addAll(new ArrayList<>(modelMappingInfoList));
                        } else {
                            modelMappingInfoMaps.put(mlProjectId, new ArrayList<>(modelMappingInfoList));
                        }
                    });

                    batchRefactoringModelDTO.setModelMappingInfosMap(modelMappingInfoMap);
                    batchRefactoringModelDTOList.add(batchRefactoringModelDTO);
                });
                // 执行重构，每个方案重构一次
                Map<String, Map<String, MetaClassInstance>> allBatchReconstructionMap = new HashMap<>();
                batchRefactoringModelDTOList.forEach(batchRefactoringModelDTO -> {
                    Map<String, Map<String, MetaClassInstance>> batchReconstructionMap = batchReconstruction(batchRefactoringModelDTO);
                    allBatchReconstructionMap.putAll(batchReconstructionMap);
                });
                schemeBasedReconstructionVO.setCopyInfoVos(targetCopyInfoVos);
                schemeBasedReconstructionVO.setRefactorCopyInfos(getRefactorCopyInfo(projectId,
                        allBatchReconstructionMap, modelMappingInfoMaps, schemeBasedReconstructionDTO.getReuseStrategy()));
            } else {
                Map<String, List<ModelMappingInfo>> modelMappingInfoMap = new HashMap<>();
                BatchRefactoringModelDTO batchRefactoringModelDTO = new BatchRefactoringModelDTO();
                batchRefactoringModelDTO.setProjectId(projectId);
                batchRefactoringModelDTO.setClassifierBehaviorStrategy(classifierBehaviorStrategy);
                batchRefactoringModelDTO.setNamingStrategy(duplicateNameHandlingStrategy);
                batchRefactoringModelDTO.setReuseStrategy(schemeBasedReconstructionDTO.getReuseStrategy());
                refactoringSchemeInfos.forEach(refactoringSchemeInfo -> {
                    List<RefactoringSchemeDefinition> refactoringSchemeDefinitions = refactoringSchemeInfo.getRefactoringSchemeDefinitions();
                    Map<String, List<RefactoringSchemeDefinition>> refactoringSchemeDefinitionMap = refactoringSchemeDefinitions.stream()
                            .collect(Collectors.groupingBy(RefactoringSchemeDefinition::getModelLibraryProjectId));
                    refactoringSchemeDefinitionMap.forEach((mlProjectId, value) -> {
                        List<ModelMappingInfo> modelMappingInfoList = value.stream().map(it -> {
                            ModelMappingInfo modelMappingInfo = new ModelMappingInfo();
                            // 重构的是原始模型
                            modelMappingInfo.setInstanceId(it.getInstanceId());
                            modelMappingInfo.setModelLibraryInstanceId(it.getModelLibraryInstanceId());
                            return modelMappingInfo;
                        }).collect(Collectors.toList());
                        modelMappingInfoMap.put(mlProjectId, modelMappingInfoList);
                    });
                });
                batchRefactoringModelDTO.setModelMappingInfosMap(modelMappingInfoMap);
                // 执行重构
                Map<String, Map<String, MetaClassInstance>> batchReconstructionMap = batchReconstruction(batchRefactoringModelDTO);
                schemeBasedReconstructionVO.setRefactorCopyInfos(getRefactorCopyInfo(projectId,
                        batchReconstructionMap, modelMappingInfoMap, schemeBasedReconstructionDTO.getReuseStrategy()));
            }
            transactionService.commit(projectId);
            InstanceVoUtils.fillModelResultVo(schemeBasedReconstructionVO, transaction);
        } catch (TransactionNotExistingException | LocalTransactionNotStartException e) {
            throw AbortExecutionException.build(ErrorCode.TRANSACTION_ERROR, e);
        } catch (Exception e) {
            transactionService.rollBack(projectId, transaction);
            throw AbortExecutionException.build(ErrorCode.ADD_MODEL_ERROR, e);
        }

        return schemeBasedReconstructionVO;
    }

    private List<RefactoringSchemeDefinitionVO> getChildNode(String projectId, MetaClassInstance instance,
                                                             Set<String> instanceIds, int remainingDepth,
                                                             List<ModelLibraryElementInfo> conformsConstraintElements,
                                                             List<ModelLibraryElementInfo> notComplyConstraintElements,
                                                             Map<String, Double> recommendedPriorityMap) {
        List<MetaClassInstance> partPropertyList = internalUmlService.queryListInstanceProperty(projectId, instance,
                UMLDefinitionConstants.Class_ownedAttribute).stream().filter(it ->
                internalUmlService.checkInstanceType(projectId, it, UMLDefinitionConstants.Customization_PartProperty))
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(partPropertyList)) {
            return Collections.emptyList();
        }

        QueryPropertyForm queryTypeForm = internalUmlService.getQueryPropertyForm(partPropertyList,
                UMLDefinitionConstants.TypedElement_type);
        MofResultContainer typeContainer = internalUmlService.queryProperty(projectId, queryTypeForm);
        List<MetaClassInstance> typeList = partPropertyList.stream().map(partProperty -> typeContainer.queryInstanceProperty(partProperty.getId(),
                UMLDefinitionConstants.TypedElement_type)).filter(Objects::nonNull).collect(Collectors.toList());

        QueryPropertyForm queryNameForm = internalUmlService.getQueryPropertyForm(typeList,
                UMLDefinitionConstants.NamedElement_name);
        MofResultContainer nameContainer = internalUmlService.queryProperty(projectId, queryNameForm);

        return typeList.stream().filter(it -> !instanceIds.contains(it.getId())
                && !internalUmlService.checkInstanceType(projectId, it, UMLDefinitionConstants.SysML_ConstraintBlock)).map(type -> {
            RefactoringSchemeDefinitionVO refactoringSchemeDefinitionVO = new RefactoringSchemeDefinitionVO();
            String typeId = type.getId();
            instanceIds.add(typeId);
            SelectElementItem selectElementItem = new SelectElementItem();
            selectElementItem.setInstanceId(typeId);
            selectElementItem.setName(nameContainer.queryStringProperty(typeId,
                    UMLDefinitionConstants.NamedElement_name));
            selectElementItem.setIcon(internalModelIconService.queryIcon(projectId, type));
            refactoringSchemeDefinitionVO.setOriginalElement(selectElementItem);

            refactoringSchemeDefinitionVO.setAdaptiveElement(buildAdaptiveElement(projectId, type,
                    conformsConstraintElements, notComplyConstraintElements, recommendedPriorityMap));

            // 加子节点，为了判断是否有子节点从而决定要不要展开
            if (remainingDepth > 0) {
                Set<String> newInstanceIds = new HashSet<>(instanceIds);
                newInstanceIds.add(typeId);
                refactoringSchemeDefinitionVO.setChildNodeInfos(getChildNode(projectId, type, new HashSet<>(instanceIds),
                        remainingDepth - 1, conformsConstraintElements, notComplyConstraintElements, recommendedPriorityMap));
            } else {
                refactoringSchemeDefinitionVO.setChildNodeInfos(Collections.emptyList());
            }
            return refactoringSchemeDefinitionVO;
        }).collect(Collectors.toList());
    }

    /**
     * 约束模型计算
     *
     * @param modelLibraryElementInfoList 所有模型库中元素信息集合
     * @param conditionalConstraints      约束条件
     * @return org.apache.commons.lang3.tuple.Pair<java.util.List < com.huawang.mdesign.model.service.facade.dto.modellibrary.ModelLibraryElementInfo>,java.util.List<com.huawang.mdesign.model.service.facade.dto.modellibrary.ModelLibraryElementInfo>>
     * @author baibf
     * @date 2025/05/20 13:53
     */
    private Pair<List<ModelLibraryElementInfo>, List<ModelLibraryElementInfo>> constraintElementCalculation(List<ModelLibraryElementInfo> modelLibraryElementInfoList,
                                                                                                            List<ConditionalSet> conditionalConstraints) {

        // 符合约束的元素
        List<ModelLibraryElementInfo> conformsConstraintList = new ArrayList<>();
        // 不符合约束的元素
        List<ModelLibraryElementInfo> notComplyConstraintList = new ArrayList<>();

        List<ConditionConstruct> conditionConstructList = conditionalConstraints.stream().map(this::conditionCalculation)
                .collect(Collectors.toList());

        modelLibraryElementInfoList.forEach(modelLibraryElementInfo -> {
            // 一个模型库中的元素信息
            String mlProjectId = modelLibraryElementInfo.getMlProjectId();
            List<String> instanceIds = modelLibraryElementInfo.getInstanceIds();
            MofResultContainer blockContainer = modelLibraryElementInfo.getBlockContainer();
            MofResultContainer attributeContainer = modelLibraryElementInfo.getAttributeContainer();
            MofResultContainer valueContainer = modelLibraryElementInfo.getValueContainer();
            Map<String, String> mlIconMap = modelLibraryElementInfo.getMlIconMap();

            List<String> conformsConstraintIds = new ArrayList<>();
            List<String> notComplyConstraintIds = new ArrayList<>();
            instanceIds.forEach(instanceId -> {
                // 当前模型库中的每一个元素
                String blName = blockContainer.queryStringProperty(instanceId, UMLDefinitionConstants.NamedElement_name);
                List<MetaClassInstance> ownedAttributes = blockContainer.queryListInstanceProperty(instanceId,
                        UMLDefinitionConstants.Class_ownedAttribute);
                List<String> parts = new ArrayList<>();
                List<String> ports = new ArrayList<>();
                List<String> valueProperties = new ArrayList<>();
                classifyAttribute(mlProjectId, ownedAttributes, parts, ports, valueProperties);
                List<String> vpNames = new ArrayList<>();
                Map<String, Object> nameAndValueMap = new HashMap<>();
                List<String> partNames = new ArrayList<>();
                List<String> portNames = new ArrayList<>();
                if (Objects.nonNull(attributeContainer)) {
                    vpNames = valueProperties.stream().map(partId -> attributeContainer.queryStringProperty(partId,
                            UMLDefinitionConstants.NamedElement_name)).collect(Collectors.toList());
                    nameAndValueMap = getNameAndValue(mlProjectId, valueProperties, attributeContainer,
                            valueContainer);
                    partNames = parts.stream().map(partId -> attributeContainer.queryStringProperty(partId,
                            UMLDefinitionConstants.NamedElement_name)).collect(Collectors.toList());
                    portNames = ports.stream().map(portId -> attributeContainer.queryStringProperty(portId,
                            UMLDefinitionConstants.NamedElement_name)).collect(Collectors.toList());
                }

                boolean conditionSetFlag = false;
                for (ConditionConstruct conditionConstruct : conditionConstructList) {
                    // xxxSate标识当前模型是否满足约束中的一种场景描述
                    List<String> elementNames = conditionConstruct.getElementNames();
                    Boolean eNameSate = CollectionUtils.isEmpty(elementNames) || elementNames.stream().anyMatch(blName::contains);
                    List<String> valuePropertyExists = conditionConstruct.getValuePropertyExists();
                    Boolean vpNameState = CollectionUtils.isEmpty(valuePropertyExists) || valuePropertyExists.stream().anyMatch(vpNames::contains);
                    List<Pair<String, String>> valuePropertyNums = conditionConstruct.getValuePropertyNums();
                    Boolean valuePropertyNumSate = judgingQuantity(valuePropertyNums, valueProperties.size());
                    List<ValuePropertyNameAndDefaultValueInfo> valuePropertyNameAndDefaultValues = conditionConstruct.getValuePropertyNameAndDefaultValues();
                    Boolean vpNAndVState = judgingVPNameAndDefaultValue(nameAndValueMap, valuePropertyNameAndDefaultValues);
                    List<String> partExists = conditionConstruct.getPartExists();
                    Boolean paNameState = CollectionUtils.isEmpty(partExists) || partExists.stream().anyMatch(partNames::contains);
                    List<Pair<String, String>> partNums = conditionConstruct.getPartNums();
                    Boolean partNumSate = judgingQuantity(partNums, parts.size());
                    List<String> portExists = conditionConstruct.getPortExists();
                    Boolean poNameState = CollectionUtils.isEmpty(portExists) || portExists.stream().anyMatch(portNames::contains);
                    List<Pair<String, String>> portNums = conditionConstruct.getPortNums();
                    Boolean portNumSate = judgingQuantity(portNums, ports.size());
                    boolean conditionFlag = computationalLogicAndGate(Stream.of(eNameSate, vpNameState, valuePropertyNumSate,
                            vpNAndVState, paNameState, partNumSate, poNameState, portNumSate).collect(Collectors.toList()));

                    if (conditionFlag) {
                        // 条件集合之间取或逻辑
                        conditionSetFlag = true;
                        break;
                    }
                }
                if (conditionSetFlag) {
                    conformsConstraintIds.add(instanceId);
                } else {
                    notComplyConstraintIds.add(instanceId);
                }
            });
            conformsConstraintList.add(new ModelLibraryElementInfo(mlProjectId, conformsConstraintIds,
                    blockContainer, attributeContainer, valueContainer, mlIconMap));
            notComplyConstraintList.add(new ModelLibraryElementInfo(mlProjectId, notComplyConstraintIds,
                    blockContainer, attributeContainer, valueContainer, mlIconMap));
        });
        return Pair.of(conformsConstraintList, notComplyConstraintList);
    }

    /**
     * 条件计算：将条件集合中的所有条件分为8类
     *
     * @param conditionalSet 条件集合
     * @return com.huawang.mdesign.model.service.facade.dto.modellibrary.ConditionConstruct
     * @author baibf
     * @date 2025/05/20 14:21
     */
    private ConditionConstruct conditionCalculation(ConditionalSet conditionalSet) {
        List<String> elementNameList = new ArrayList<>();
        List<String> valuePropertyExistList = new ArrayList<>();
        List<Pair<String, String>> valuePropertyNumList = new ArrayList<>();
        List<ValuePropertyNameAndDefaultValueInfo> valuePropertyNameAndDefaultValueList = new ArrayList<>();
        List<String> partExistList = new ArrayList<>();
        List<Pair<String, String>> partNumList = new ArrayList<>();
        List<String> portExistList = new ArrayList<>();
        List<Pair<String, String>> portNumList = new ArrayList<>();
        List<Condition> conditions = conditionalSet.getConditions();
        for (Condition condition : conditions) {
            String sceneDescription = condition.getSceneDescription();
            if (StringUtils.isEmpty(sceneDescription)) {
                continue;
            }
            List<ConstraintCondition> constraintConditions = condition.getConstraintConditions();
            ConstraintCondition constraintCondition = constraintConditions.get(0);
            if (StringUtils.equals(sceneDescription, ELEMENT_NAME)) {
                definiteConstraintDescription(constraintCondition, elementNameList);
            } else if (StringUtils.equals(sceneDescription, VALUE_PROPERTY_EXIST)) {
                definiteConstraintDescription(constraintCondition, valuePropertyExistList);
            } else if (StringUtils.equals(sceneDescription, VALUE_PROPERTY_NUM)) {
                uncertainConstraintDescription(constraintCondition, valuePropertyNumList);
            } else if (StringUtils.equals(sceneDescription, VALUE_PROPERTY_NAME_AND_DEFAULT_VALUE)) {
                ConstraintCondition constraintCondition1 = constraintConditions.get(1);
                valuePropertyNameAndDefaultValueList.add(new ValuePropertyNameAndDefaultValueInfo(constraintCondition.getConstraintValue(),
                        constraintCondition1.getConstraintType(), constraintCondition1.getConstraintValue()));
            } else if (StringUtils.equals(sceneDescription, PART_EXIST)) {
                definiteConstraintDescription(constraintCondition, partExistList);
            } else if (StringUtils.equals(sceneDescription, PART_NUM)) {
                uncertainConstraintDescription(constraintCondition, partNumList);
            } else if (StringUtils.equals(sceneDescription, PORT_EXIST)) {
                definiteConstraintDescription(constraintCondition, portExistList);
            } else if (StringUtils.equals(sceneDescription, PORT_NUM)) {
                uncertainConstraintDescription(constraintCondition, portNumList);
            } else {
                log.info("其他场景描述：{}", sceneDescription);
            }
        }
        return ConditionConstruct.builder()
                .elementNames(elementNameList)
                .valuePropertyExists(valuePropertyExistList)
                .valuePropertyNums(valuePropertyNumList)
                .valuePropertyNameAndDefaultValues(valuePropertyNameAndDefaultValueList)
                .partExists(partExistList)
                .partNums(partNumList)
                .portExists(portExistList)
                .portNums(portNumList)
                .build();
    }

    /**
     * 确定的约束条件描述
     *
     * @param constraintCondition 约束条件
     * @param stringList          约束值的集合
     * @return void
     * @author baibf
     * @date 2025/05/20 14:23
     */
    private static void definiteConstraintDescription(ConstraintCondition constraintCondition, List<String> stringList) {
        String constraintValue = constraintCondition.getConstraintValue();
        if (StringUtils.isNotEmpty(constraintValue)) {
            stringList.add(constraintValue);
        }
    }

    /**
     * 确定的约束条件描述
     *
     * @param constraintCondition 约束条件
     * @param numList             运算符与约束值的映射集合
     * @return void
     * @author baibf
     * @date 2025/05/20 14:24
     */
    private static void uncertainConstraintDescription(ConstraintCondition constraintCondition,
                                                       List<Pair<String, String>> numList) {
        String constraintValue = constraintCondition.getConstraintValue();
        if (StringUtils.isNotEmpty(constraintValue)) {
            numList.add(Pair.of(constraintCondition.getConstraintType(), constraintValue));
        }
    }


    private Map<String, Object> getNameAndValue(String mlProjectId, List<String> valueProperties,
                                                MofResultContainer attributeContainer, MofResultContainer valueContainer) {
        Map<String, Object> nameAndValueMap = new HashMap<>();
        for (String valuePropertyId : valueProperties) {
            String vpName = attributeContainer.queryStringProperty(valuePropertyId, UMLDefinitionConstants.NamedElement_name);
            MetaClassInstance defaultValue = attributeContainer.queryInstanceProperty(valuePropertyId,
                    UMLDefinitionConstants.Property_defaultValue);
            if (Objects.isNull(defaultValue) || Objects.isNull(valueContainer)) {
                continue;
            }
            Object value = null;
            if (internalUmlService.checkInstanceType(mlProjectId, defaultValue, UMLDefinitionConstants.LiteralReal)) {
                value = valueContainer.queryDoubleProperty(defaultValue.getId(),
                        UMLDefinitionConstants.LiteralReal_value);
            } else if (internalUmlService.checkInstanceType(mlProjectId, defaultValue, UMLDefinitionConstants.LiteralInteger)) {
                value = valueContainer.queryIntegerProperty(defaultValue.getId(),
                        UMLDefinitionConstants.LiteralInteger_value);
            } else if (internalUmlService.checkInstanceType(mlProjectId, defaultValue, UMLDefinitionConstants.LiteralBoolean)) {
                value = valueContainer.queryDoubleProperty(defaultValue.getId(),
                        UMLDefinitionConstants.LiteralBoolean_value);
            } else if (internalUmlService.checkInstanceType(mlProjectId, defaultValue, UMLDefinitionConstants.LiteralString)) {
                value = valueContainer.queryDoubleProperty(defaultValue.getId(), UMLDefinitionConstants.LiteralString_value);
            } else {
                log.info("其他类型类型的ValueSpecification！");
            }
            nameAndValueMap.put(vpName, value);
        }
        return nameAndValueMap;
    }


    /**
     * 判断数量
     *
     * @param numList 运算符与值映射集合
     * @param number  元素实际有的对应属性数量
     * @return boolean
     * @author baibf
     * @date 2025/05/20 14:26
     */
    private static boolean judgingQuantity(List<Pair<String, String>> numList, int number) {
        boolean flag = true;
        if (CollectionUtils.isEmpty(numList)) {
            return flag;
        }
        boolean mutualExclusion = isMutualExclusion(numList);
        if (mutualExclusion) {
            return flag;
        }
        for (Pair<String, String> num : numList) {
            String operator = num.getLeft();
            String value = num.getRight();
            int intVale = Integer.parseInt(value);
            if (StringUtils.equals(operator, GT)) {
                flag = flag && number > intVale;
            } else if (StringUtils.equals(operator, LT)) {
                flag = flag && number < intVale;
            } else if (StringUtils.equals(operator, GE)) {
                flag = flag && number >= intVale;
            } else if (StringUtils.equals(operator, LE)) {
                flag = flag && number <= intVale;
            } else {
                flag = flag && number == intVale;
            }
        }
        return flag;
    }

    // 判断多个条件是否互斥
    private static boolean isMutualExclusion(List<Pair<String, String>> numList) {

        // 初始化数轴范围
        double min = Double.NEGATIVE_INFINITY;
        double max = Double.POSITIVE_INFINITY;
        boolean includeMin = true;  // 是否包含最小值
        boolean includeMax = true;  // 是否包含最大值

        // 记录等式条件（最多只能有一个有效）
        Integer equalityValue = null;

        // 遍历条件并更新范围
        for (Pair<String, String> num : numList) {
            String operator = num.getLeft();
            String value = num.getRight();
            int intVale = Integer.parseInt(value);
            switch (operator) {
                case GT:
                    Pair<Double, Boolean> gtPair = greater(intVale, min, includeMin, operator);
                    min = gtPair.getLeft();
                    includeMin = gtPair.getRight();
                    break;
                case GE:
                    Pair<Double, Boolean> gePair = greater(intVale, min, includeMin, operator);
                    min = gePair.getLeft();
                    includeMin = gePair.getRight();
                    break;
                case LT:
                    Pair<Double, Boolean> ltPair = less(intVale, max, includeMax, operator);
                    max = ltPair.getLeft();
                    includeMax = ltPair.getRight();
                    break;
                case LE:
                    Pair<Double, Boolean> lePair = less(intVale, max, includeMax, operator);
                    max = lePair.getLeft();
                    includeMax = lePair.getRight();
                    break;
                case EQ:
                    // 多个等式条件必须值相同
                    if (equalityValue != null && equalityValue != intVale) {
                        return true; // 互斥
                    }
                    equalityValue = intVale;
                    break;
                default:
                    break;
            }
            // 检查范围是否有效  边界相等时需检查是否包含边界
            if (min > max || (min == max && (!includeMin || !includeMax))) {
                return true; // 互斥
            }
        }
        // 检查等式条件是否在范围内
        if (equalityValue != null) {
            // 检查等式值是否在[min, max]范围内
            if (equalityValue < min || equalityValue > max) {
                return true; // 互斥
            }

            // 边界相等时的包含检查
            if (equalityValue == min && !includeMin) {
                return true;
            }
            if (equalityValue == max && !includeMax) {
                return true;
            }
        }
        return false; // 不互斥
    }

    private static Pair<Double, Boolean> greater(int intVale, double min, boolean includeMin, String operator) {
        if (StringUtils.equals(operator, GT)) {
            if (intVale >= min) {
                min = intVale;
                includeMin = false;
            }
        } else {
            if (intVale > min || (intVale == min && includeMin)) {
                min = intVale;
                includeMin = true;
            }
        }
        return Pair.of(min, includeMin);
    }

    private static Pair<Double, Boolean> less(int intVale, double max, boolean includeMax, String operator) {
        if (StringUtils.equals(operator, LT)) {
            if (intVale <= max) {
                max = intVale;
                includeMax = false;
            }
        } else {
            if (intVale < max || (intVale == max && includeMax)) {
                max = intVale;
                includeMax = true;
            }
        }
        return Pair.of(max, includeMax);
    }

    private static boolean judgingVPNameAndDefaultValue(Map<String, Object> nameAndValueMap,
                                                        List<ValuePropertyNameAndDefaultValueInfo> valuePropertyNameAndDefaultValues) {
        if (CollectionUtils.isEmpty(valuePropertyNameAndDefaultValues)) {
            return true;
        }
        for (Map.Entry<String, Object> entry : nameAndValueMap.entrySet()) {
            String vpName = entry.getKey();
            Object vpValue = entry.getValue();
            if (Objects.isNull(vpValue)) {
                continue;
            }
            boolean flag = true;
            for (ValuePropertyNameAndDefaultValueInfo valuePropertyNameAndDefaultValue : valuePropertyNameAndDefaultValues) {
                String name = valuePropertyNameAndDefaultValue.getName();
                boolean flagName = true;
                if (StringUtils.isNotEmpty(name)) {
                    flagName = StringUtils.equals(vpName, name);
                }

                String operator = valuePropertyNameAndDefaultValue.getOperator();
                String value = valuePropertyNameAndDefaultValue.getValue();
                boolean flagValue = true;
                if (StringUtils.isNotEmpty(value)) {
                    if (vpValue instanceof Double || vpValue instanceof Integer) {
                        flagValue = numericalCalculation(vpValue, value, operator);
                    } else if (vpValue instanceof Boolean) {
                        flagValue = booleanCalculation(vpValue, value);
                    } else {
                        flagValue = StringUtils.equals(vpValue.toString(), value);
                    }
                }
                flag = flag && flagName && flagValue;
            }
            if (flag) {
                return true;
            }
        }
        return false;
    }

    /**
     * 数字计算
     *
     * @param vpValue  值属性的值
     * @param value    实际的约束值
     * @param operator 运算符
     * @return boolean
     * @author baibf
     * @date 2025/05/20 14:29
     */
    private static boolean numericalCalculation(Object vpValue, String value, String operator) {
        if (vpValue instanceof Double) {
            double v = Double.parseDouble(value);
            if (StringUtils.equals(operator, GT)) {
                return v > (Double) vpValue;
            } else if (StringUtils.equals(operator, LT)) {
                return v < (Double) vpValue;
            } else if (StringUtils.equals(operator, GE)) {
                return v >= (Double) vpValue;
            } else if (StringUtils.equals(operator, LE)) {
                return v <= (Double) vpValue;
            } else {
                return v == (Double) vpValue;
            }
        } else if (vpValue instanceof Integer) {
            int i = Integer.parseInt(value);
            if (StringUtils.equals(operator, GT)) {
                return i > (Integer) vpValue;
            } else if (StringUtils.equals(operator, LT)) {
                return i < (Integer) vpValue;
            } else if (StringUtils.equals(operator, GE)) {
                return i >= (Integer) vpValue;
            } else if (StringUtils.equals(operator, LE)) {
                return i <= (Integer) vpValue;
            } else {
                return i == (Integer) vpValue;
            }
        }
        return false;
    }

    /**
     * Boolean计算
     *
     * @param vpValue 值属性的值
     * @param value   实际的约束值
     * @return boolean
     * @author baibf
     * @date 2025/05/20 14:31
     */
    private static boolean booleanCalculation(Object vpValue, String value) {
        String key = value.trim().toLowerCase();
        Boolean parsedValue = BOOLEAN_MAP.get(key);
        return parsedValue.equals(vpValue);
    }


    // 条件之间取与的逻辑
    private static boolean computationalLogicAndGate(List<Boolean> andGateList) {
        boolean flag = true;
        for (Boolean andGate : andGateList) {
            flag = flag && andGate;
        }
        return flag;
    }

    /**
     * 根据策略获取对应的权重
     *
     * @param recommendedPriority
     * @return java.util.Map<java.lang.String, java.lang.Double>
     * @author baibf
     * @date 2025/05/20 14:32
     */
    private static Map<String, Double> recommendedPriorityHandle(RecommendedPriority recommendedPriority) {
        String selectStrategy = recommendedPriority.getSelectStrategy();
        Double nameWeight = recommendedPriority.getNameWeight();  // 名称权重
        Double structureWeight = recommendedPriority.getStructureWeight();  // 结构权重
        Double portWeight = recommendedPriority.getPortWeight();  // 端口权重
        Double parameterWeight = recommendedPriority.getParameterWeight();  // 参数权重
        double sum = nameWeight + structureWeight + portWeight + parameterWeight;
        if (StringUtils.equals(selectStrategy, CUSTOMIZE) && sum != 1.0) {
            nameWeight = nameWeight / sum;
            structureWeight = structureWeight / sum;
            portWeight = structureWeight / sum;
            parameterWeight = 1.0 - (nameWeight + structureWeight + portWeight);
        }
        Map<String, Double> valueMap = new HashMap<>();
        valueMap.put("a1", nameWeight);
        valueMap.put("a2", structureWeight);
        valueMap.put("a3", portWeight);
        valueMap.put("a4", parameterWeight);
        return valueMap;
    }


    /**
     * 构建适配模型
     *
     * @param projectId
     * @param instance                    当前模型
     * @param conformsConstraintElements  符合约束的模型集合
     * @param notComplyConstraintElements 不符合约束的模型集合
     * @param recommendedPriorityMap      策略权重Map
     * @return com.huawang.mdesign.model.service.vo.modellibrary.AdaptiveElement
     * @author baibf
     * @date 2025/05/20 13:50
     */
    private AdaptiveElement buildAdaptiveElement(String projectId, MetaClassInstance instance,
                                                 List<ModelLibraryElementInfo> conformsConstraintElements,
                                                 List<ModelLibraryElementInfo> notComplyConstraintElements,
                                                 Map<String, Double> recommendedPriorityMap) {
        List<AdaptiveElementInfo> eligibleAdaptiveElements = adaptiveElementsCalculation(projectId, instance,
                conformsConstraintElements, recommendedPriorityMap);
        List<AdaptiveElementInfo> noncomplianceAdaptiveElements = adaptiveElementsCalculation(projectId, instance,
                notComplyConstraintElements, recommendedPriorityMap);
        AdaptiveElement adaptiveElement = new AdaptiveElement();
        adaptiveElement.setEligibleAdaptiveElements(eligibleAdaptiveElements);
        adaptiveElement.setNoncomplianceAdaptiveElements(noncomplianceAdaptiveElements);
        return adaptiveElement;
    }

    /**
     * 适配模型计算
     *
     * @param projectId
     * @param instance               当前项目中的模型
     * @param constraintElements     模型库中的模型信息集合
     * @param recommendedPriorityMap 策略权重Map
     * @return java.util.List<com.huawang.mdesign.model.service.vo.modellibrary.AdaptiveElementInfo>
     * @author baibf
     * @date 2025/05/20 14:39
     */
    private List<AdaptiveElementInfo> adaptiveElementsCalculation(String projectId, MetaClassInstance instance,
                                                                  List<ModelLibraryElementInfo> constraintElements,
                                                                  Map<String, Double> recommendedPriorityMap) {
        return constraintElements.stream().flatMap(conformsConstraintElement -> {
            String mlProjectId = conformsConstraintElement.getMlProjectId();
            List<String> instanceIds = conformsConstraintElement.getInstanceIds();
            MofResultContainer blockContainer = conformsConstraintElement.getBlockContainer();
            MofResultContainer attributeContainer = conformsConstraintElement.getAttributeContainer();
            Map<String, String> mlIconMap = conformsConstraintElement.getMlIconMap();
            return instanceIds.stream().map(mlInstanceId -> {
                AdaptiveElementInfo adaptiveElementInfo = new AdaptiveElementInfo();
                Map<String, Double> parameterMap = calculationParameter(projectId, instance, mlProjectId, mlInstanceId,
                        blockContainer, attributeContainer);
                // 推荐度计算
                double ms = recommendedPriorityMap.get("a1") * parameterMap.get("s_name") +
                        recommendedPriorityMap.get("a2") * parameterMap.get("s_structure") +
                        recommendedPriorityMap.get("a3") * parameterMap.get("s_port") +
                        recommendedPriorityMap.get("a4") * parameterMap.get("s_value");
                adaptiveElementInfo.setModelLibraryProjectId(mlProjectId);
                adaptiveElementInfo.setInstanceId(mlInstanceId);
                adaptiveElementInfo.setName(blockContainer.queryStringProperty(mlInstanceId,
                        UMLDefinitionConstants.NamedElement_name));
                adaptiveElementInfo.setIcon(mlIconMap.get(mlInstanceId));
                adaptiveElementInfo.setRecommendationLevel(ms);
                return adaptiveElementInfo;
            });
        }).collect(Collectors.toList());
    }

    /**
     * 各权重对应参数计算
     *
     * @param projectId
     * @param instance
     * @param mlProjectId
     * @param mlInstanceId
     * @param blockContainer
     * @param attributeContainer
     * @return java.util.Map<java.lang.String, java.lang.Double>
     * @author baibf
     * @date 2025/05/20 14:41
     */
    private Map<String, Double> calculationParameter(String projectId, MetaClassInstance instance,
                                                     String mlProjectId, String mlInstanceId,
                                                     MofResultContainer blockContainer, MofResultContainer attributeContainer) {
        String moduleName = internalUmlService.queryStringProperty(projectId, instance,
                UMLDefinitionConstants.NamedElement_name);
        List<MetaClassInstance> ownedAttributes = internalUmlService.queryListInstanceProperty(projectId, instance,
                UMLDefinitionConstants.Class_ownedAttribute);
        List<String> systemStructures = new ArrayList<>();
        List<String> portStructures = new ArrayList<>();
        List<String> systemParameters = new ArrayList<>();
        classifyAttribute(mlProjectId, ownedAttributes, systemStructures, portStructures, systemParameters);
        QueryPropertyForm queryNameForm = internalUmlService.getQueryPropertyForm(ownedAttributes, UMLDefinitionConstants.NamedElement_name);
        MofResultContainer nameContainer = internalUmlService.queryProperty(projectId, queryNameForm);
        Map<String, String> ownedAttributeNameMap = ownedAttributes.stream().collect(Collectors.toMap(BasicRElement::getId,
                it1 -> nameContainer.queryStringProperty(it1.getId(), UMLDefinitionConstants.NamedElement_name), (k, v) -> k));

        String instanceName = blockContainer.queryStringProperty(mlInstanceId, UMLDefinitionConstants.NamedElement_name);
        List<MetaClassInstance> mlOwnedAttributes = blockContainer.queryListInstanceProperty(mlInstanceId, UMLDefinitionConstants.Class_ownedAttribute);
        List<String> parts = new ArrayList<>();
        List<String> ports = new ArrayList<>();
        List<String> valueProperties = new ArrayList<>();
        classifyAttribute(mlProjectId, mlOwnedAttributes, parts, ports, valueProperties);
        Map<String, String> mlOwnedAttributeNameMap = mlOwnedAttributes.stream().collect(Collectors.toMap(BasicRElement::getId,
                it1 -> attributeContainer.queryStringProperty(it1.getId(), UMLDefinitionConstants.NamedElement_name), (k, v) -> k));


        int repeatCharacter = countCommonCharacters(moduleName, instanceName);
        double moduleNameLength = 1.0;
        if (StringUtils.isNotEmpty(moduleName)) {
            moduleNameLength = moduleName.length();
        }
        double sName = repeatCharacter / moduleNameLength;
        Map<String, Double> parameterMap = new HashMap<>();

        Set<String> systemStructureSet = systemStructures.stream().map(ownedAttributeNameMap::get).collect(Collectors.toSet());
        Set<String> partSet = parts.stream().map(mlOwnedAttributeNameMap::get).collect(Collectors.toSet());
        double a = 1;
        double systemStructuresLength = systemStructures.size();
        if (systemStructuresLength != 0) {
            a = systemStructureSet.stream().filter(partSet::contains).count() / systemStructuresLength;
        }
        double b = 1;
        systemStructuresLength = systemStructures.size() + (double) parts.size();
        if (systemStructuresLength != 0) {
            b = Math.abs(systemStructures.size() - parts.size()) / systemStructuresLength;
        }
        double sStructure = 0.2 * a + 0.8 * (1 - b);

        Set<String> portStructureSet = portStructures.stream().map(ownedAttributeNameMap::get).collect(Collectors.toSet());
        Set<String> portSet = ports.stream().map(mlOwnedAttributeNameMap::get).collect(Collectors.toSet());
        double c = 1;
        double portStructureLength = portStructures.size();
        if (portStructureLength != 0) {
            c = portStructureSet.stream().filter(portSet::contains).count() / portStructureLength;
        }
        double d = 1;
        portStructureLength = portStructures.size() + (double) ports.size();
        if (portStructureLength != 0) {
            d = Math.abs(portStructures.size() - ports.size()) / portStructureLength;
        }
        double sPort = 0.2 * c + 0.8 * (1 - d);

        Set<String> systemParameterSet = systemParameters.stream().map(ownedAttributeNameMap::get).collect(Collectors.toSet());
        Set<String> valuePropertySet = valueProperties.stream().map(mlOwnedAttributeNameMap::get).collect(Collectors.toSet());

        double e = 1;
        double systemParameterLength = systemParameters.size();
        if (systemParameterLength != 0) {
            e = systemParameterSet.stream().filter(valuePropertySet::contains).count() / systemParameterLength;
        }
        double f = 1;
        systemParameterLength = systemParameters.size() + (double) valueProperties.size();
        if (systemParameterLength != 0) {
            f = Math.abs(systemParameters.size() - valueProperties.size()) / systemParameterLength;
        }

        double sValue = 0.5 * e + 0.5 * (1 - f);

        parameterMap.put("s_name", sName);
        parameterMap.put("s_structure", sStructure);
        parameterMap.put("s_port", sPort);
        parameterMap.put("s_value", sValue);
        return parameterMap;
    }


    /**
     * 判断两个字符中有几个形同的字符
     *
     * @param str1
     * @param str2
     * @return int
     * @author baibf
     * @date 2025/05/20 14:43
     */
    private static int countCommonCharacters(String str1, String str2) {
        // 创建两个集合存储唯一字符
        Set<Character> set1 = getUniqueCharacters(str1);
        Set<Character> set2 = getUniqueCharacters(str2);

        // 计算交集
        Set<Character> intersection = new HashSet<>(set1);
        intersection.retainAll(set2);

        return intersection.size();
    }

    private static Set<Character> getUniqueCharacters(String str) {
        Set<Character> uniqueChars = new HashSet<>();
        for (char c : str.toCharArray()) {
            uniqueChars.add(c);
        }
        return uniqueChars;
    }


    /**
     * 根据属性类型分类
     *
     * @param projectId
     * @param attributes      所有的Property
     * @param parts           结构属性集合
     * @param ports           端口
     * @param valueProperties 值属性集合
     * @return void
     * @author baibf
     * @date 2025/05/20 14:03
     */
    private void classifyAttribute(String projectId, List<MetaClassInstance> attributes, List<String> parts,
                                   List<String> ports, List<String> valueProperties) {
        attributes.forEach(attribute -> {
            if (internalUmlService.checkInstanceType(projectId, attribute, UMLDefinitionConstants.Customization_PartProperty)
                    || internalUmlService.checkInstanceType(projectId, attribute, UMLDefinitionConstants.Customization_ConstraintProperty)) {
                parts.add(attribute.getId());
            } else if (internalUmlService.checkInstanceType(projectId, attribute, UMLDefinitionConstants.Port)) {
                ports.add(attribute.getId());
            } else if (internalUmlService.checkInstanceType(projectId, attribute, UMLDefinitionConstants.Customization_ValueProperty)) {
                valueProperties.add(attribute.getId());
            } else {
                log.info("属性是其他类型！");
            }
        });
    }

    /**
     * 根据属性类型分类
     *
     * @param projectId
     * @param attributes
     * @param partList
     * @param portList
     * @param parameterList
     * @param nameContainer
     * @param iconMap
     * @return void
     * @author baibf
     * @date 2025/05/20 14:42
     */
    private void classifyAttribute(String projectId, List<MetaClassInstance> attributes, List<SelectElementItem> partList,
                                   List<SelectElementItem> portList, List<SelectElementItem> parameterList,
                                   MofResultContainer nameContainer, Map<String, String> iconMap) {
        attributes.forEach(it -> {
            String attributeId = it.getId();
            SelectElementItem selectElementItem = new SelectElementItem();
            selectElementItem.setInstanceId(attributeId);
            selectElementItem.setName(nameContainer.queryStringProperty(attributeId, UMLDefinitionConstants.NamedElement_name));
            selectElementItem.setIcon(iconMap.get(attributeId));
            if (internalUmlService.checkInstanceType(projectId, it, UMLDefinitionConstants.Customization_PartProperty)
                    || internalUmlService.checkInstanceType(projectId, it, UMLDefinitionConstants.Customization_ConstraintProperty)) {
                partList.add(selectElementItem);
            } else if (internalUmlService.checkInstanceType(projectId, it, UMLDefinitionConstants.Port)) {
                portList.add(selectElementItem);
            } else if (internalUmlService.checkInstanceType(projectId, it, UMLDefinitionConstants.Customization_ValueProperty)) {
                parameterList.add(selectElementItem);
            } else {
                log.info("属性是其他类型！");
            }
        });
    }

    public CopyResultVo reconstruction(RefactoringModelDTO refactoringModelDTO) {
        log.info("reconstruction===>refactoringModelDTO:{}", refactoringModelDTO);
        String projectId = refactoringModelDTO.getProjectId();

        BatchRefactoringModelDTO batchRefactoringModelDTO = transferToBatchRefactoringModelDTO(refactoringModelDTO);
        CopyResultVo copyResultVo = new CopyResultVo();
        LocalTransaction transaction = transactionService.createTransaction(projectId, COPY_MODEL);
        try {
            Map<String, Map<String, MetaClassInstance>> resultMap = batchReconstruction(batchRefactoringModelDTO);
            List<Map<String, MetaClassInstance>> list = new ArrayList<>(resultMap.values());
            Map<String, MetaClassInstance> copyInfoMap = Optional.of(list).filter(CollectionUtils::isNotEmpty).map(e -> e.get(0)).orElse(Collections.emptyMap());
            transactionService.commit(projectId);
            InstanceVoUtils.fillCopyResultVo(copyResultVo, transaction, copyInfoMap);
        } catch (TransactionNotExistingException | LocalTransactionNotStartException e) {
            throw AbortExecutionException.build(ErrorCode.TRANSACTION_ERROR, e);
        } catch (AbortExecutionException abortExecutionException) {
            log.error("occur exception", abortExecutionException);
            transactionService.rollBack(projectId, transaction);
            throw AbortExecutionException.build(abortExecutionException.getCode(), abortExecutionException.getMessage(), abortExecutionException.getTitleForm().getContent(), abortExecutionException.getLevel());
        } catch (Exception e) {
            log.error("occur exception", e);
            transactionService.rollBack(projectId, transaction);
            throw AbortExecutionException.build(ErrorCode.UPDATE_MODEL_ERROR, e);
        }
        return copyResultVo;
    }

    /**
     * @param batchRefactoringModelDTO
     * @return Map<String, Map < String, MetaClassInstance>> key：模型id,value:复制的模型
     */
    private Map<String, Map<String, MetaClassInstance>> batchReconstruction(BatchRefactoringModelDTO batchRefactoringModelDTO) {
        String projectId = batchRefactoringModelDTO.getProjectId();
        //全部替换逻辑
        if (Objects.equals(batchRefactoringModelDTO.getReuseStrategy(), RefactoringModelReuseStrategy.REPLACE_ALL.getCode())) {
            Map<String, Map<String, MetaClassInstance>> resultMap = new HashMap<>();
            Map<String, List<ModelMappingInfo>> modelMappingInfosMap = batchRefactoringModelDTO.getModelMappingInfosMap();

            Map<String, String> instanceMergeMap = new HashMap<>();
            Map<String, Map<String, Set<String>>> affectedInstanceAttributesMap = new HashMap<>();
            Map<String, MetaClassInstance> replaceInstanceMap = new HashMap<>();
            Map<String, Map<MetaClassInstance, Map<String, MetaClassInstance>>> needUpdateGlobalNumberMap = new HashMap<>();
            for (Map.Entry<String, List<ModelMappingInfo>> entry : modelMappingInfosMap.entrySet()) {
                String libraryProjectId = entry.getKey();
                List<ModelMappingInfo> modelMappingInfos = entry.getValue();
                Map<String, String> instanceIdMap = modelMappingInfos.stream().collect(Collectors.toMap(ModelMappingInfo::getInstanceId, ModelMappingInfo::getModelLibraryInstanceId, (k1, k2) -> k1));

                List<String> instanceIds = new ArrayList<>(instanceIdMap.keySet());
                Map<String, MetaClassInstance> metaClassInstanceMap = internalUmlService.fetchInstances(instanceIds, projectId);


                List<String> libraryInstanceIds = new ArrayList<>(instanceIdMap.values());
                Map<String, MetaClassInstance> libraryMetaClassInstanceMap = internalUmlService.fetchInstances(libraryInstanceIds, libraryProjectId);


                List<String> ownerIds = metaClassInstanceMap.values().stream().map(MetaClassInstance::getOwnerId).collect(Collectors.toList());
                Map<String, MetaClassInstance> ownerInstanceMap = internalUmlService.fetchInstances(ownerIds, projectId);

                for (Map.Entry<String, String> instanceIdEntry : instanceIdMap.entrySet()) {
                    String instanceId = instanceIdEntry.getKey();
                    String libraryInstanceId = instanceIdEntry.getValue();
                    MetaClassInstance instance = metaClassInstanceMap.get(instanceId);
                    String instanceOwnerId = instance.getOwnerId();
                    MetaClassInstance ownerInstance = ownerInstanceMap.get(instanceOwnerId);

                    MetaClassInstance libraryInstance = libraryMetaClassInstanceMap.get(libraryInstanceId);


                    Map<String, MetaClassInstance> result = umlService.paste(libraryProjectId, libraryInstanceId, projectId, instanceOwnerId);
                    MetaClassInstance firstInstance = result.get(libraryInstanceId);

                    if (firstInstance == null) {
                        throw AbortExecutionException.build(ErrorCode.COPY_ERROR);
                    }

                    modelService.metaTypeConfigHandler(projectId, result);

                    // 复制粘贴后置处理
                    pasteSupplement.pastePostProcessor(projectId, firstInstance, ownerInstance, result);
                    // 粘贴后模型编号处理
                    globalNumberGenerator.pasteElementSetNumber(libraryProjectId, projectId, libraryInstance, result);

                    Map<MetaClassInstance, Map<String, MetaClassInstance>> innerMap = needUpdateGlobalNumberMap.getOrDefault(libraryProjectId, new HashMap<>());
                    innerMap.put(libraryInstance, result);
                    needUpdateGlobalNumberMap.putIfAbsent(libraryProjectId, innerMap);

                    instanceMergeMap.put(firstInstance.getId(), instanceId);
                    resultMap.put(firstInstance.getId(), result);
                    replaceInstanceMap.put(instanceId, firstInstance);

                    List<EncapsulationService.ReferenceInfo> affectedAttributes = encapsulationService.getReferenceInfo(projectId, instanceId);
                    fillAffectedInstanceAttributeMap(affectedAttributes, affectedInstanceAttributesMap, projectId, instance);
                }
            }


            List<String> newInstanceIds = new ArrayList<>(instanceMergeMap.keySet());
            List<String> mergePropertyInstanceIds = new ArrayList<>(instanceMergeMap.values());
            Map<String, ReconstructionEntity> reconstructionEntitiesMap = createReconstructionEntitiesMap(projectId, newInstanceIds);

            Map<String, ReconstructionEntity> mergePropertyReconstructionEntityMap = createReconstructionEntitiesMap(projectId, mergePropertyInstanceIds);

            List<UpdateModelDTO> updateModelDTOS = new ArrayList<>();
            List<String> deleteInstanceIds = new ArrayList<>();

            for (Map.Entry<String, String> instanceMergeEntry : instanceMergeMap.entrySet()) {

                String instanceId = instanceMergeEntry.getKey();
                String mergeInstanceId = instanceMergeEntry.getValue();


                ReconstructionEntity reconstructionEntity = reconstructionEntitiesMap.get(instanceId);
                ReconstructionEntity mergeReconstructionEntity = mergePropertyReconstructionEntityMap.get(mergeInstanceId);
                Map<String, ModelPropertyInfo> modelPropertyInfoMap = reconstructionEntity.getModelPropertyInfoMap();
                Map<String, ModelPropertyInfo> modelLibraryModelPropertyInfoMap = mergeReconstructionEntity.getModelPropertyInfoMap();

                //修改端口类型
                Map<List<String>, List<String>> portGivenTypesGroupedInstanceIdsMap = getGivenTypesGroupedInstanceIdsMap(reconstructionEntity.getInstanceIdGivenTypesMap(), reconstructionEntity.getPortMetaClassInstances());

                Map<List<String>, List<String>> modelLibraryPortGivenTypesGroupedInstanceIdsMap = getGivenTypesGroupedInstanceIdsMap(mergeReconstructionEntity.getInstanceIdGivenTypesMap(), mergeReconstructionEntity.getPortMetaClassInstances());
                List<UpdateModelDTO> portUpdateTypedTypeDTOs = getUpdateTypedTypeDTOs(portGivenTypesGroupedInstanceIdsMap, modelLibraryPortGivenTypesGroupedInstanceIdsMap,
                        modelPropertyInfoMap, modelLibraryModelPropertyInfoMap, projectId);
                updateModelDTOS.addAll(portUpdateTypedTypeDTOs);

                //修改部件、约束类型
                Map<List<String>, List<String>> partConstraintGivenTypesGroupedInstanceIdsMap = getGivenTypesGroupedInstanceIdsMap(reconstructionEntity.getInstanceIdGivenTypesMap(),
                        reconstructionEntity.getPartConstraintMetaClassInstances());
                Map<List<String>, List<String>> modelLibraryPartConstraintGivenTypesGroupedInstanceIdsMap = getGivenTypesGroupedInstanceIdsMap(mergeReconstructionEntity.getInstanceIdGivenTypesMap(),
                        mergeReconstructionEntity.getPartConstraintMetaClassInstances());
                List<UpdateModelDTO> partConstraintUpdateTypedTypeDTOs = getUpdateTypedTypeDTOs(partConstraintGivenTypesGroupedInstanceIdsMap, modelLibraryPartConstraintGivenTypesGroupedInstanceIdsMap,
                        modelPropertyInfoMap, modelLibraryModelPropertyInfoMap, projectId);
                updateModelDTOS.addAll(partConstraintUpdateTypedTypeDTOs);
                deleteInstanceIds.add(mergeInstanceId);

            }


            //更新即将被删除元素的影响元素
            List<UpdateModelDTO> affectedAttributesUpdateModelDTOS = getAffectedAttributesUpdateModelDTOS(affectedInstanceAttributesMap, replaceInstanceMap, projectId);
            invokeUpdateOperation(affectedAttributesUpdateModelDTOS);

            umlService.updateModelByBatch(updateModelDTOS);
            if (CollectionUtils.isNotEmpty(deleteInstanceIds)) {
                modelService.businessDeleteByIds(projectId, deleteInstanceIds);
            }

            //粘贴后对需求编号进行修改
            needUpdateGlobalNumberMap.forEach((libraryProjectId, innerMap) ->
                    innerMap.forEach((libraryInstance, result) -> {
                        globalNumberGenerator.pasteElementSetNumber(libraryProjectId, projectId, libraryInstance, result);
                        //重命名
                        MetaClassInstance firstInstance = result.get(libraryInstance.getId());
                        umlService.rename(projectId, firstInstance);

                        //对复制生成的模型进行instance属性设置
                        Set<String> needUpdateIds = result.values().stream().map(MetaClassInstance::getId).collect(Collectors.toSet());
                        updateCopyInstanceProperties(needUpdateIds, result, libraryProjectId, projectId);
                    })
            );
            return resultMap;

        }
        //保持结构与定义
        return getReconstructionResultMap(batchRefactoringModelDTO);
    }

    private List<UpdateModelDTO> getUpdateTypedTypeDTOs(Map<List<String>, List<String>> portGivenTypesGroupedInstanceIdsMap, Map<List<String>, List<String>> modelLibraryPortGivenTypesGroupedInstanceIdsMap, Map<String, ModelPropertyInfo> modelPropertyInfoMap, Map<String, ModelPropertyInfo> modelLibraryModelPropertyInfoMap, String projectId) {
        Map<List<String>, List<String>> intersectionGivenTypesGroupedInstanceIdsMap = portGivenTypesGroupedInstanceIdsMap.entrySet().stream().filter(e -> modelLibraryPortGivenTypesGroupedInstanceIdsMap.containsKey(e.getKey())).
                collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (k1, k2) -> k1));
        List<UpdateModelDTO> updateModelDTOS = new ArrayList<>();
        intersectionGivenTypesGroupedInstanceIdsMap.forEach((givenTypes, tempInstanceIds) -> {

            Map<String, String> namesInstanceIdMap = tempInstanceIds.stream().collect(Collectors.toMap(tempInstanceId -> modelPropertyInfoMap.get(tempInstanceId).
                    queryStringValue(UMLDefinitionConstants.NamedElement_name), Function.identity(), (k1, k2) -> k1));

            List<String> modelLibraryInstanceIds = modelLibraryPortGivenTypesGroupedInstanceIdsMap.getOrDefault(givenTypes, Collections.emptyList());
            Map<String, String> modelLibraryNamesInstanceIdMap = modelLibraryInstanceIds.stream().collect(Collectors.toMap(tempInstanceId -> modelLibraryModelPropertyInfoMap.get(tempInstanceId).
                    queryStringValue(UMLDefinitionConstants.NamedElement_name), Function.identity(), (k1, k2) -> k1));


            Map<String, String> dumplicateNameInstanceIdMap = namesInstanceIdMap.entrySet().stream().filter(e -> modelLibraryNamesInstanceIdMap.containsKey(e.getKey())).
                    collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (k1, k2) -> k2));

            //存在重名的时候修改重名属性类型

            dumplicateNameInstanceIdMap.forEach((modelInstanceName, modelInstanceId) -> {
                String libraryInstanceId = modelLibraryNamesInstanceIdMap.get(modelInstanceName);

                MetaClassInstance typedTypeMetaClassInstance = modelLibraryModelPropertyInfoMap.get(libraryInstanceId).queryInstanceValue(UMLDefinitionConstants.TypedElement_type);

                if (typedTypeMetaClassInstance != null) {
                    UpdateModelDTO typeUpdateModelDTO = UpdateModelFactory.newInstance(projectId, modelInstanceId, UMLDefinitionConstants.TypedElement_type, typedTypeMetaClassInstance);
                    updateModelDTOS.add(typeUpdateModelDTO);
                }

            });

        });
        return updateModelDTOS;
    }

    private Map<String, Map<String, MetaClassInstance>> getReconstructionResultMap(BatchRefactoringModelDTO batchRefactoringModelDTO) {
        String projectId = batchRefactoringModelDTO.getProjectId();
        List<ModelRefactoringResult> results = getModelRefactoringResults(batchRefactoringModelDTO);
        //处理重构信息执行重构操作
        List<UpdateModelDTO> updateModelDTOS = new ArrayList<>();

        Map<String, Map<String, MetaClassInstance>> resultMap = new HashMap<>();
        for (ModelRefactoringResult modelRefactoringResult : results) {
            String modelLibraryProjectId = modelRefactoringResult.getModelLibraryProjectId();
            String targetMetaClassInstanceId = modelRefactoringResult.getMetaClassInstanceId();
            Map<String, MetaClassInstance> replaceMetaInstanceMap = new HashMap<>();
            Map<MetaClassInstance, Map<String, MetaClassInstance>> groupedOldNewInstanceMap = new HashMap<>();


            ModelPropertyInfo modelPropertyInfo = modelRefactoringResult.getModelPropertyInfo();
            ModelPropertyInfo modelLibraryPropertyInfo = modelRefactoringResult.getModelLibraryPropertyInfo();

            //处理构造型属性，合并两者构造型，取并集
            List<MetaClassInstance> stereotypes = modelPropertyInfo.queryListInstanceValue(UMLDefinitionConstants.Element_appliedStereotype);
            Set<String> stereotypeIds = stereotypes.stream().map(MetaClassInstance::getId).collect(Collectors.toSet());
            List<MetaClassInstance> libraryStereotypes = modelLibraryPropertyInfo.queryListInstanceValue(UMLDefinitionConstants.Element_appliedStereotype);
            List<MetaClassInstance> needAddStereotypes = libraryStereotypes.stream().filter(e -> !stereotypeIds.contains(e.getId())).collect(Collectors.toList());

            if (CollectionUtils.isNotEmpty(needAddStereotypes)) {
                List<MetaClassInstance> mergedStereotypes = Stream.concat(stereotypes.stream(), needAddStereotypes.stream()).collect(Collectors.toList());
                UpdateModelDTO stereotypeUpdateModelDTO = UpdateModelFactory.newInstance(projectId, targetMetaClassInstanceId, UMLDefinitionConstants.Element_appliedStereotype, mergedStereotypes);
                umlService.updateModelByBatch(stereotypeUpdateModelDTO);
            }

            Map<String, Map<String, Set<String>>> affectedInstanceAttributesMap = new HashMap<>();

            List<ModelPropertyRefactoringResult> portModelPropertyRefactoringResults = modelRefactoringResult.getPortModelPropertyRefactoringResults();
            merge(modelRefactoringResult, portModelPropertyRefactoringResults, affectedInstanceAttributesMap, replaceMetaInstanceMap, groupedOldNewInstanceMap);

            List<ModelPropertyRefactoringResult> partConstraintModelPropertyRefactoringResults = modelRefactoringResult.getPartConstraintModelPropertyRefactoringResults();
            merge(modelRefactoringResult, partConstraintModelPropertyRefactoringResults, affectedInstanceAttributesMap, replaceMetaInstanceMap, groupedOldNewInstanceMap);

            List<ModelPropertyRefactoringResult> nestedClassifierModelPropertyRefactoringResults = modelRefactoringResult.getNestedClassifierModelPropertyRefactoringResults();
            merge(modelRefactoringResult, nestedClassifierModelPropertyRefactoringResults, affectedInstanceAttributesMap, replaceMetaInstanceMap, groupedOldNewInstanceMap);


            //处理嵌套分类器属性,保留结构与定义，需要合并重构元素与被重构元素的嵌套分类器
            if (CollectionUtils.isNotEmpty(nestedClassifierModelPropertyRefactoringResults)) {
                List<MetaClassInstance> nestedClassifierMetaClassInstances = modelPropertyInfo.queryListInstanceValue(UMLDefinitionConstants.Class_nestedClassifier);
                List<MetaClassInstance> newNestedClassifierMetaClassInstances = nestedClassifierMetaClassInstances.stream().filter(e -> !replaceMetaInstanceMap.containsKey(e.getId())).collect(Collectors.toList());

                List<MetaClassInstance> modelLibraryNestedClassifierMetaClassInstances = modelLibraryPropertyInfo.queryListInstanceValue(UMLDefinitionConstants.Class_nestedClassifier);


                List<MetaClassInstance> newModelLibraryNestedClassifierMetaClassInstances = modelLibraryNestedClassifierMetaClassInstances.stream().filter(groupedOldNewInstanceMap::containsKey).
                        map(e -> groupedOldNewInstanceMap.get(e).get(e.getId())).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(newModelLibraryNestedClassifierMetaClassInstances)) {
                    newNestedClassifierMetaClassInstances.addAll(newModelLibraryNestedClassifierMetaClassInstances);
                    UpdateModelDTO nestedClassifierUpdateModelDTO = UpdateModelFactory.newInstance(projectId, targetMetaClassInstanceId, UMLDefinitionConstants.Class_nestedClassifier, newNestedClassifierMetaClassInstances);
                    umlService.updateModelByBatch(nestedClassifierUpdateModelDTO);

                }
            }

            List<ModelPropertyRefactoringResult> otherModelPropertyRefactoringResults = modelRefactoringResult.getOtherModelPropertyRefactoringResults();
            merge(modelRefactoringResult, otherModelPropertyRefactoringResults, affectedInstanceAttributesMap, replaceMetaInstanceMap, groupedOldNewInstanceMap);

            List<ModelPropertyRefactoringResult> classifierBehaviorModelPropertyRefactoringResults = modelRefactoringResult.getClassifierBehaviorModelPropertyRefactoringResults();
            merge(modelRefactoringResult, classifierBehaviorModelPropertyRefactoringResults, affectedInstanceAttributesMap, replaceMetaInstanceMap, groupedOldNewInstanceMap);

            Map<String, MetaClassInstance> oldNewInstanceMap = new HashMap<>();
            groupedOldNewInstanceMap.forEach((instance, map) -> oldNewInstanceMap.putAll(map));
            Set<String> totalNeedUpdateInstanceIdSet = oldNewInstanceMap.values().stream().map(MetaClassInstance::getId).collect(Collectors.toSet());
            //对复制的Instance属性进行设置
            updateCopyInstanceProperties(totalNeedUpdateInstanceIdSet, oldNewInstanceMap, modelLibraryProjectId, projectId);

            resultMap.put(targetMetaClassInstanceId, oldNewInstanceMap);

            List<UpdateModelDTO> affectedAttributesUpdateModelDTOS = getAffectedAttributesUpdateModelDTOS(affectedInstanceAttributesMap, replaceMetaInstanceMap, projectId);

            invokeUpdateOperation(affectedAttributesUpdateModelDTOS);


            //处理分类器行为
            if (Objects.equals(batchRefactoringModelDTO.getClassifierBehaviorStrategy().getClassifierBehaviorReplace(), Boolean.TRUE)) {
                MetaClassInstance behaviorClassifierMetaClassInstance = modelLibraryPropertyInfo.queryInstanceValue(UMLDefinitionConstants.BehavioredClassifier_classifierBehavior);
                if (Objects.nonNull(behaviorClassifierMetaClassInstance)) {
                    MetaClassInstance newBehaviorClassifierMetaClassInstance = oldNewInstanceMap.get(behaviorClassifierMetaClassInstance.getId());
                    if (Objects.nonNull(newBehaviorClassifierMetaClassInstance)) {
                        ModifyPropertyDTO modifyPropertyDTO = new ModifyPropertyDTO();
                        modifyPropertyDTO.setInstanceId(targetMetaClassInstanceId);
                        modifyPropertyDTO.setProjectId(projectId);
                        modifyPropertyDTO.setDataType(TypeEnum.INSTANCE.getName());
                        modifyPropertyDTO.setKey(UMLDefinitionConstants.BehavioredClassifier_classifierBehavior);
                        modifyPropertyDTO.setValue(Collections.singletonList(newBehaviorClassifierMetaClassInstance.getId()));
                        modifyPropertyDTO.setIsMultiplicity(false);
                        propertyManager.updatePropertyValue(modifyPropertyDTO);
                    }
                }
            }
            List<ModelPropertyRefactoringResult> allModelPropertyRefactoringResults = new ArrayList<>();
            allModelPropertyRefactoringResults.addAll(portModelPropertyRefactoringResults);
            allModelPropertyRefactoringResults.addAll(partConstraintModelPropertyRefactoringResults);
            allModelPropertyRefactoringResults.addAll(nestedClassifierModelPropertyRefactoringResults);
            allModelPropertyRefactoringResults.addAll(classifierBehaviorModelPropertyRefactoringResults);
            allModelPropertyRefactoringResults.addAll(otherModelPropertyRefactoringResults);
            List<ModelPropertyRefactoringResult> filteredNeedUpdateGlobalNumberResults = allModelPropertyRefactoringResults.stream().filter(e -> Objects.equals(e.getOperation(), ModelPropertyOperationEnum.ADD) ||
                    Objects.equals(e.getOperation(), ModelPropertyOperationEnum.REPLACE)).collect(Collectors.toList());

            filteredNeedUpdateGlobalNumberResults.forEach(e ->
                    // 粘贴后模型编号处理
                    globalNumberGenerator.pasteElementSetNumber(modelLibraryProjectId, projectId, e.getMetaClassInstance(), groupedOldNewInstanceMap.getOrDefault(e.getMetaClassInstance(), Collections.emptyMap()))
            );

        }
        umlService.updateModelByBatch(updateModelDTOS);
        return resultMap;
    }

    /**
     * 执行合并
     *
     * @param modelRefactoringResult
     * @param allPropertyRefactoringResults
     * @param affectedInstanceAttributesMap
     * @param replaceMetaInstanceMap
     * @param groupedOldNewInstanceMap
     */
    private void merge(ModelRefactoringResult modelRefactoringResult, List<ModelPropertyRefactoringResult> allPropertyRefactoringResults,
                       Map<String, Map<String, Set<String>>> affectedInstanceAttributesMap, Map<String, MetaClassInstance> replaceMetaInstanceMap, Map<MetaClassInstance, Map<String, MetaClassInstance>> groupedOldNewInstanceMap) {
        List<ModelPropertyRefactoringResult> needCopyModelPropertyRefactoringResults = allPropertyRefactoringResults.stream().filter(e -> Objects.equals(e.getOperation(), ModelPropertyOperationEnum.ADD) ||
                Objects.equals(e.getOperation(), ModelPropertyOperationEnum.REPLACE)).collect(Collectors.toList());

        List<ModelPropertyRefactoringResult> needDeleteModelPropertyRefactoringResults = allPropertyRefactoringResults.stream().
                filter(e -> Objects.equals(e.getOperation(), ModelPropertyOperationEnum.DELETE)).collect(Collectors.toList());
        List<String> needDeleteMetaClassInstanceIds = needDeleteModelPropertyRefactoringResults.stream().map(ModelPropertyRefactoringResult::getMetaClassInstanceId).collect(Collectors.toList());

        //执行copy操作
        doCopyOperation(modelRefactoringResult, needCopyModelPropertyRefactoringResults, affectedInstanceAttributesMap, replaceMetaInstanceMap, groupedOldNewInstanceMap);
        if (CollectionUtils.isNotEmpty(needDeleteMetaClassInstanceIds)) {
            modelService.businessDeleteByIds(modelRefactoringResult.getProjectId(), needDeleteMetaClassInstanceIds);
        }
    }

    /**
     * 执行复制
     *
     * @param modelRefactoringResult
     * @param needCopyModelPropertyRefactoringResults
     * @param affectedInstanceAttributesMap
     * @param replaceMetaInstanceMap
     * @param groupedOldNewInstanceMap
     */
    private void doCopyOperation(ModelRefactoringResult modelRefactoringResult, List<ModelPropertyRefactoringResult> needCopyModelPropertyRefactoringResults,
                                 Map<String, Map<String, Set<String>>> affectedInstanceAttributesMap, Map<String, MetaClassInstance> replaceMetaInstanceMap, Map<MetaClassInstance, Map<String, MetaClassInstance>> groupedOldNewInstanceMap) {
        String modelLibraryProjectId = modelRefactoringResult.getModelLibraryProjectId();
        String targetProjectId = modelRefactoringResult.getProjectId();
        String targetMetaClassInstanceId = modelRefactoringResult.getMetaClassInstanceId();

        for (ModelPropertyRefactoringResult needCopyModelPropertyRefactoringResult : needCopyModelPropertyRefactoringResults) {
            String modelLibraryMetaClassInstanceId = needCopyModelPropertyRefactoringResult.getMetaClassInstanceId();
            MetaClassInstance modelLibraryMetaClassInstance = needCopyModelPropertyRefactoringResult.getMetaClassInstance();


            Map<String, MetaClassInstance> result = umlService.paste(modelLibraryProjectId, modelLibraryMetaClassInstanceId,
                    targetProjectId, targetMetaClassInstanceId);
            result.values().forEach(it -> {
                if (internalUmlService.checkInstanceType(targetProjectId, it, UMLDefinitionConstants.SysML_Requirement)) {
                    umlService.removeModel(targetProjectId, it.getId(), UMLDefinitionConstants.SysML_AbstractRequirement_id);
                }
            });
            Map<String, UpdateModelDTO> propertyKeyUpdateModelDTOMap = needCopyModelPropertyRefactoringResult.getUpdateModelDTOS().stream().
                    collect(Collectors.toMap(UpdateModelDTO::getPropertyId, Function.identity(), (k1, k2) -> k1));
            // 粘贴出来的模型
            MetaClassInstance firstInstance = result.get(modelLibraryMetaClassInstanceId);

            if (firstInstance == null) {
                throw AbortExecutionException.build(ErrorCode.COPY_ERROR);
            }

            //如果存在名称重复修改了名称的情况，这里复制出来的新模型需要更新名称
            if (propertyKeyUpdateModelDTOMap.containsKey(UMLDefinitionConstants.NamedElement_name)) {
                UpdateModelDTO nameUpdateDTO = propertyKeyUpdateModelDTOMap.remove(UMLDefinitionConstants.NamedElement_name);
                nameUpdateDTO.setInstanceId(firstInstance.getId());
                umlService.updateModelByBatch(nameUpdateDTO);
            }
            //如果存在类型更新操作
            if (propertyKeyUpdateModelDTOMap.containsKey(UMLDefinitionConstants.TypedElement_type)) {
                UpdateModelDTO typeUpdateDTO = propertyKeyUpdateModelDTOMap.remove(UMLDefinitionConstants.TypedElement_type);
                typeUpdateDTO.setInstanceId(firstInstance.getId());
                umlService.updateModelByBatch(typeUpdateDTO);
            }
            //构建影响属性map
            List<EncapsulationService.ReferenceInfo> affectedAttributes = needCopyModelPropertyRefactoringResult.getAffectedAttributes();
            MetaClassInstance replaceMetaClassInstance = needCopyModelPropertyRefactoringResult.getReplaceMetaClassInstance();
            if (Objects.nonNull(replaceMetaClassInstance) && CollectionUtils.isNotEmpty(affectedAttributes)) {
                fillAffectedInstanceAttributeMap(affectedAttributes, affectedInstanceAttributesMap, modelRefactoringResult.getProjectId(), needCopyModelPropertyRefactoringResult.getReplaceMetaClassInstance());
            }

            //如果图形的上下文不为空，那么进行替换

            MetaClassInstance diagramContext = internalUmlService.queryInstanceProperty(modelLibraryProjectId, modelLibraryMetaClassInstance, UMLDefinitionConstants.Diagram_context);
            if (diagramContext != null) {
                umlService.updateModel(targetProjectId, firstInstance.getId(), UMLDefinitionConstants.Diagram_context, modelRefactoringResult.getMetaClassInstance());
            }


            modelService.metaTypeConfigHandler(targetProjectId, result);

            // 复制粘贴后置处理
            pasteSupplement.pastePostProcessor(targetProjectId, firstInstance, modelRefactoringResult.getMetaClassInstance(), result);

            String replaceMetaClassInstanceId = needCopyModelPropertyRefactoringResult.getReplaceMetaClassInstanceId();
            if (StringUtils.isNotBlank(replaceMetaClassInstanceId)) {
                replaceMetaInstanceMap.put(replaceMetaClassInstanceId, firstInstance);
            }
            groupedOldNewInstanceMap.put(modelLibraryMetaClassInstance, result);
        }
    }

    /**
     * 执行更新操作
     *
     * @param updateModelDTOS
     */
    private void invokeUpdateOperation(List<UpdateModelDTO> updateModelDTOS) {
        //更新受影响属性
        for (UpdateModelDTO updateModelDTO : updateModelDTOS) {
            try {
                umlService.updateModelByBatch(updateModelDTO);
            } catch (RuntimeException exception) {
                log.error("执行" + updateModelDTO.toString() + "报错", exception);
            }
        }
    }

    private void fillAffectedInstanceAttributeMap(List<EncapsulationService.ReferenceInfo> affectedAttributes, Map<String, Map<String, Set<String>>> affectedInstanceAttributesMap, String projectId, MetaClassInstance replaceMetaClassInstance) {
        List<String> affectedInstanceIds = affectedAttributes.stream().map(EncapsulationService.ReferenceInfo::getInstanceId).collect(Collectors.toList());
        List<MetaClassInstance> affectedMetaClassInstances = internalUmlService.fetchInstanceByIds(affectedInstanceIds, projectId);


        Set<String> skipInstanceIds = affectedMetaClassInstances.stream()
                .filter(it -> !internalUmlService.checkInstanceType(projectId, it, UMLDefinitionConstants.Relationship))
                .map(BasicRElement::getId)
                .collect(Collectors.toSet());

        List<EncapsulationService.ReferenceInfo> filteredInstances = affectedAttributes.stream().filter(e -> !skipInstanceIds.contains(e.getInstanceId())).collect(Collectors.toList());
        filteredInstances.forEach(e -> {
            String instanceId = e.getInstanceId();
            List<String> affectPropertyKeys = e.getAffectPropertyKeys();
            List<String> filteredPropertyKeys = affectPropertyKeys.stream().filter(propertyKey -> {
                if (elementCheckService.isOwnerProperty(projectId, propertyKey) && replaceMetaClassInstance.getOwnerId().equals(instanceId)) {
                    return false;
                }
                // 图例的指定属性不需要覆盖
                return !UMLDefinitionConstants.Customization_LegendItem_SpecificElements.equals(propertyKey);
            }).collect(Collectors.toList());
            Map<String, Set<String>> affectedPropertyValueMap = affectedInstanceAttributesMap.getOrDefault(instanceId, new HashMap<>());
            filteredPropertyKeys.forEach(propertyKey -> {
                Set<String> affectedPropertyValues = affectedPropertyValueMap.getOrDefault(propertyKey, new HashSet<>());
                affectedPropertyValues.add(replaceMetaClassInstance.getId());
                affectedPropertyValueMap.putIfAbsent(propertyKey, affectedPropertyValues);
            });
            affectedInstanceAttributesMap.putIfAbsent(instanceId, affectedPropertyValueMap);

        });
    }

    /**
     * 更新复制的模型的内部属性
     *
     * @param oldNewInstanceMap
     * @param projectId
     */
    private void updateCopyInstanceProperties(Set<String> totalNeedUpdateInstanceIdsSet, Map<String, MetaClassInstance> oldNewInstanceMap, String libraryProjectId, String projectId) {
        List<UpdateModelDTO> updateModelDTOS = new ArrayList<>();
        List<ModifyPropertyDTO> modifyPropertyDTOList = new ArrayList<>();

        List<MetaClassInstance> needUpdatePropertyInstanceList = internalUmlService.fetchInstanceByIds(new ArrayList<>(totalNeedUpdateInstanceIdsSet), projectId);
        List<MetaClassInstance> oldMetaClassInstances = internalUmlService.fetchInstanceByIds(new ArrayList<>(oldNewInstanceMap.keySet()), libraryProjectId);
        Map<String, MetaClassInstance> oldMetaClassInstancesMap = oldMetaClassInstances.stream().collect(Collectors.toMap(MetaClassInstance::getId, Function.identity(), (k1, k2) -> k1));

        Map<String, String> newOldInstanceIdMap = oldNewInstanceMap.entrySet().stream().collect(Collectors.toMap(entry -> entry.getValue().getId(), Map.Entry::getKey, (k1, k2) -> k1));
        Map<List<String>, List<String>> typePropertiesMap = new HashMap<>();
        for (MetaClassInstance needUpdatePropertyInstance : needUpdatePropertyInstanceList) {
            List<String> typeIdList = Stream.concat(needUpdatePropertyInstance.getAppliedStereotypes().stream(), Stream.of(needUpdatePropertyInstance.getMetaClass().getId())).sorted().collect(Collectors.toList());
            List<String> needProperties = typePropertiesMap.getOrDefault(typeIdList, modelService.getNeedPropertiesByTypeIds(typeIdList, projectId)).stream().filter(e -> {
                String dataType = internalUmlService.queryPropertyDataType(projectId, e);
                return Objects.equals(dataType, TypeEnum.INSTANCE.getName());
            }).collect(Collectors.toList());

            typePropertiesMap.putIfAbsent(typeIdList, needProperties);
            //查询属性多重性
            Map<String, Boolean> propertyKeyMultiplicityMap = internalUmlService.isMultiplicity(projectId, needProperties);

            Map<String, MofPropertyInfo> oldPropertyValueMap = Collections.emptyMap();
            String oldId = newOldInstanceIdMap.get(needUpdatePropertyInstance.getId());
            if (oldId != null && oldMetaClassInstancesMap.containsKey(oldId)) {
                oldPropertyValueMap = internalUmlService.queryPropertyByKeys(libraryProjectId, oldMetaClassInstancesMap.get(oldId), needProperties);
            }

            for (String needProperty : needProperties) {
                MofPropertyInfo oldMofPropertyInfo = oldPropertyValueMap.get(needProperty);

                boolean isMultiplicity = propertyKeyMultiplicityMap.get(needProperty);
                Object values = getOldValues(oldMofPropertyInfo);
                if (values == null) {
                    continue;
                }

                List<MetaClassInstance> metaClassInstances = isMultiplicity ? ((List<MetaClassInstance>) values) : Collections.singletonList((MetaClassInstance) values);

                List<MetaClassInstance> newMetaClassInstances = metaClassInstances.stream().filter(e -> oldNewInstanceMap.containsKey(e.getId())).map(metaClassInstance ->
                        oldNewInstanceMap.get(metaClassInstance.getId())).collect(Collectors.toList());
                Set<String> newMetaClassInstanceIds = newMetaClassInstances.stream().map(MetaClassInstance::getId).collect(Collectors.toSet());

                if (CollectionUtils.isNotEmpty(newMetaClassInstanceIds)) {
                    if (COMPUTED_PROPERTIES_NEED_COPY.contains(needProperty)) {
                        List<Object> needModifyMetaClassInstanceIds = newMetaClassInstances.stream().map(e -> (Object) e.getId()).collect(Collectors.toList());
                        ModifyPropertyDTO modifyPropertyDTO = new ModifyPropertyDTO();
                        modifyPropertyDTO.setInstanceId(needUpdatePropertyInstance.getId());
                        modifyPropertyDTO.setProjectId(projectId);
                        modifyPropertyDTO.setDataType(TypeEnum.INSTANCE.getName());
                        modifyPropertyDTO.setKey(needProperty);
                        modifyPropertyDTO.setValue(needModifyMetaClassInstanceIds);
                        modifyPropertyDTO.setIsMultiplicity(isMultiplicity);
                        modifyPropertyDTOList.add(modifyPropertyDTO);
                    } else {

                        Object updateValue = isMultiplicity ? newMetaClassInstances : newMetaClassInstances.get(0);
                        UpdateModelDTO updateModelDTO = UpdateModelFactory.newInstance(projectId, needUpdatePropertyInstance.getId(), needProperty, updateValue);
                        updateModelDTOS.add(updateModelDTO);
                    }
                }
            }

        }
        //执行更新属性操作
        invokeUpdateOperation(updateModelDTOS);

        //执行计算属性更新操作
        invokeModifyPropertyOperation(modifyPropertyDTOList);
    }

    private Object getOldValues(MofPropertyInfo oldMofPropertyInfo) {
        if (Objects.isNull(oldMofPropertyInfo)) {
            return null;
        }
        Object values = oldMofPropertyInfo.getValues();

        if (values == null || (values instanceof List && CollectionUtils.isEmpty((List<?>) values))) {
            return null;
        }
        return values;
    }

    /**
     * 执行计算属性更新操作
     *
     * @param modifyPropertyDTOList
     */
    private void invokeModifyPropertyOperation(List<ModifyPropertyDTO> modifyPropertyDTOList) {
        for (ModifyPropertyDTO computedPropertyUpdateDTO : modifyPropertyDTOList) {
            try {
                propertyManager.updatePropertyValue(computedPropertyUpdateDTO);
            } catch (RuntimeException exception) {
                log.error("执行更新计算属性操作" + computedPropertyUpdateDTO.toString() + "报错", exception);
            }
        }
    }


    private List<ModelRefactoringResult> getModelRefactoringResults(BatchRefactoringModelDTO
                                                                            batchRefactoringModelDTO) {
        String projectId = batchRefactoringModelDTO.getProjectId();
        Map<String, List<ModelMappingInfo>> modelMappingInfosMap = batchRefactoringModelDTO.getModelMappingInfosMap();
        List<String> instanceIds = modelMappingInfosMap.values().stream().flatMap(Collection::parallelStream).map(ModelMappingInfo::getInstanceId).distinct().collect(Collectors.toList());
        Map<String, List<String>> projectModelLibraryInstanceIdsMap = modelMappingInfosMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey,
                e -> e.getValue().stream().map(ModelMappingInfo::getModelLibraryInstanceId).distinct().collect(Collectors.toList()), (k1, k2) -> k1));

        Map<String, ReconstructionEntity> reconstructionEntitiesMap = createReconstructionEntitiesMap(projectId, instanceIds);

        Map<String, Map<String, ReconstructionEntity>> modelLibraryReconstructionEntityMap = projectModelLibraryInstanceIdsMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey,
                entry -> createReconstructionEntitiesMap(entry.getKey(), entry.getValue()), (k1, k2) -> k2));

        List<ModelRefactoringResult> results = new ArrayList<>();
        //构建重构信息
        for (Map.Entry<String, List<ModelMappingInfo>> entry : modelMappingInfosMap.entrySet()) {
            String modelLibraryProjectId = entry.getKey();
            List<ModelMappingInfo> modelMappingInfos = entry.getValue();
            for (ModelMappingInfo modelMappingInfo : modelMappingInfos) {
                String instanceId = modelMappingInfo.getInstanceId();
                String modelLibraryInstanceId = modelMappingInfo.getModelLibraryInstanceId();
                boolean isNeedHandle = reconstructionEntitiesMap.containsKey(instanceId) && modelLibraryReconstructionEntityMap.containsKey(modelLibraryProjectId)
                        && modelLibraryReconstructionEntityMap.get(modelLibraryProjectId).containsKey(modelLibraryInstanceId);
                if (!isNeedHandle) {
                    continue;
                }

                ReconstructionEntity reconstructionEntity = reconstructionEntitiesMap.get(instanceId);
                ReconstructionEntity modelLibraryReconstructionEntity = modelLibraryReconstructionEntityMap.get(modelLibraryProjectId).get(modelLibraryInstanceId);


                ModelRefactoringResult metaInstanceRefactoringResult = new ModelRefactoringResult();
                metaInstanceRefactoringResult.setProjectId(projectId);
                metaInstanceRefactoringResult.setMetaClassInstanceId(instanceId);
                metaInstanceRefactoringResult.setModelLibraryProjectId(modelLibraryProjectId);
                metaInstanceRefactoringResult.setModelLibraryMetaClassInstanceId(modelLibraryInstanceId);
                metaInstanceRefactoringResult.setMetaClassInstance(reconstructionEntity.getParentMetaClassInstance());
                metaInstanceRefactoringResult.setModelPropertyInfo(reconstructionEntity.getParentModelInfo());
                metaInstanceRefactoringResult.setModelLibraryMetaClassInstance(modelLibraryReconstructionEntity.getParentMetaClassInstance());
                metaInstanceRefactoringResult.setModelLibraryPropertyInfo(modelLibraryReconstructionEntity.getParentModelInfo());


                DuplicateNameHandlingStrategy namingStrategy = batchRefactoringModelDTO.getNamingStrategy();
                Map<String, ModelPropertyInfo> modelPropertyInfoMap = reconstructionEntity.getModelPropertyInfoMap();
                Map<String, ModelPropertyInfo> modelLibraryModelPropertyInfoMap = modelLibraryReconstructionEntity.getModelPropertyInfoMap();
                Map<List<String>, Set<String>> givenTypesNamesMap = new HashMap<>(reconstructionEntity.getGivenTypesNamesMap());


                //创建端口重构内容
                Map<List<String>, List<String>> portGivenTypesGroupedInstanceIdsMap = getGivenTypesGroupedInstanceIdsMap(reconstructionEntity.getInstanceIdGivenTypesMap(), reconstructionEntity.getPortMetaClassInstances());

                Map<List<String>, List<String>> modelLibraryPortGivenTypesGroupedInstanceIdsMap = getGivenTypesGroupedInstanceIdsMap(modelLibraryReconstructionEntity.getInstanceIdGivenTypesMap(), modelLibraryReconstructionEntity.getPortMetaClassInstances());

                ModelRefactoringDataHolder portDataHolder = ModelRefactoringDataHolder.builder().
                        givenTypesGroupedInstanceIdsMap(portGivenTypesGroupedInstanceIdsMap).
                        modelPropertyInfoMap(modelPropertyInfoMap).
                        modelLibraryGivenTypesGroupedInstanceIdsMap(modelLibraryPortGivenTypesGroupedInstanceIdsMap).
                        modelLibraryModelPropertyInfoMap(modelLibraryModelPropertyInfoMap).
                        duplicateNameHandlingStrategy(namingStrategy.getPort()).
                        reuseStrategy(batchRefactoringModelDTO.getReuseStrategy()).
                        projectId(reconstructionEntity.getProjectId()).
                        modelLibraryProjectId(modelLibraryReconstructionEntity.getProjectId()).build();

                List<ModelPropertyRefactoringResult> portModelPropertyRefactoringResults = getModelPropertyRefactoringResults(portDataHolder, givenTypesNamesMap);

                //创建部件、约束重构内容
                Map<List<String>, List<String>> partConstraintGivenTypesGroupedInstanceIdsMap = getGivenTypesGroupedInstanceIdsMap(reconstructionEntity.getInstanceIdGivenTypesMap(),
                        reconstructionEntity.getPartConstraintMetaClassInstances());
                Map<List<String>, List<String>> modelLibraryPartConstraintGivenTypesGroupedInstanceIdsMap = getGivenTypesGroupedInstanceIdsMap(modelLibraryReconstructionEntity.getInstanceIdGivenTypesMap(),
                        modelLibraryReconstructionEntity.getPartConstraintMetaClassInstances());

                ModelRefactoringDataHolder partConstraintDataHolder = ModelRefactoringDataHolder.builder().
                        givenTypesGroupedInstanceIdsMap(partConstraintGivenTypesGroupedInstanceIdsMap).
                        modelPropertyInfoMap(modelPropertyInfoMap).
                        modelLibraryGivenTypesGroupedInstanceIdsMap(modelLibraryPartConstraintGivenTypesGroupedInstanceIdsMap).
                        modelLibraryModelPropertyInfoMap(modelLibraryModelPropertyInfoMap).
                        duplicateNameHandlingStrategy(namingStrategy.getComponentAndConstraint()).
                        reuseStrategy(batchRefactoringModelDTO.getReuseStrategy()).
                        projectId(reconstructionEntity.getProjectId()).
                        modelLibraryProjectId(modelLibraryReconstructionEntity.getProjectId()).build();
                List<ModelPropertyRefactoringResult> partConstraintModelPropertyRefactoringResults = getModelPropertyRefactoringResults(partConstraintDataHolder, givenTypesNamesMap);

                //创建内嵌分类器重构内容
                Map<List<String>, List<String>> nestedClassifierGivenTypesGroupedInstanceIdsMap = getGivenTypesGroupedInstanceIdsMap(reconstructionEntity.getInstanceIdGivenTypesMap(),
                        reconstructionEntity.getNestedClassifierMetaClassInstances());
                Map<List<String>, List<String>> modelLibraryNetstedClassifierGivenTypesGroupedInstanceIdsMap = getGivenTypesGroupedInstanceIdsMap(modelLibraryReconstructionEntity.getInstanceIdGivenTypesMap(),
                        modelLibraryReconstructionEntity.getNestedClassifierMetaClassInstances());
                ModelRefactoringDataHolder nestedClassifierDataHolder = ModelRefactoringDataHolder.builder().
                        givenTypesGroupedInstanceIdsMap(nestedClassifierGivenTypesGroupedInstanceIdsMap).
                        modelPropertyInfoMap(modelPropertyInfoMap).
                        modelLibraryGivenTypesGroupedInstanceIdsMap(modelLibraryNetstedClassifierGivenTypesGroupedInstanceIdsMap).
                        modelLibraryModelPropertyInfoMap(modelLibraryModelPropertyInfoMap).
                        duplicateNameHandlingStrategy(namingStrategy.getNestedClassifier()).
                        reuseStrategy(batchRefactoringModelDTO.getReuseStrategy()).
                        projectId(reconstructionEntity.getProjectId()).
                        modelLibraryProjectId(modelLibraryReconstructionEntity.getProjectId()).build();
                List<ModelPropertyRefactoringResult> nestedClassifierModelPropertyRefactoringResults = getModelPropertyRefactoringResults(nestedClassifierDataHolder, givenTypesNamesMap);

                //其它重构内容

                Map<List<String>, List<String>> otherGivenTypesGroupedInstanceIdsMap = getGivenTypesGroupedInstanceIdsMap(reconstructionEntity.getInstanceIdGivenTypesMap(),
                        reconstructionEntity.getOtherMetaClassInstances());
                Map<List<String>, List<String>> modelLibraryOtherGivenTypesGroupedInstanceIdsMap = getGivenTypesGroupedInstanceIdsMap(modelLibraryReconstructionEntity.getInstanceIdGivenTypesMap(),
                        modelLibraryReconstructionEntity.getOtherMetaClassInstances());
                ModelRefactoringDataHolder otherDataHolder = ModelRefactoringDataHolder.builder().
                        givenTypesGroupedInstanceIdsMap(otherGivenTypesGroupedInstanceIdsMap).
                        modelPropertyInfoMap(modelPropertyInfoMap).
                        modelLibraryGivenTypesGroupedInstanceIdsMap(modelLibraryOtherGivenTypesGroupedInstanceIdsMap).
                        modelLibraryModelPropertyInfoMap(modelLibraryModelPropertyInfoMap).
                        duplicateNameHandlingStrategy(DuplicateNameHandlingEnum.KEEP_DOUBLE_MODEL.getCode()).
                        reuseStrategy(batchRefactoringModelDTO.getReuseStrategy()).
                        projectId(reconstructionEntity.getProjectId()).
                        modelLibraryProjectId(modelLibraryReconstructionEntity.getProjectId()).build();
                List<ModelPropertyRefactoringResult> otherModelPropertyRefactoringResults = getModelPropertyRefactoringResults(otherDataHolder, givenTypesNamesMap);
                //处理分类器行为重构内容
                MetaClassInstance modelLibraryClassifierBehaviorMetaClassInstance = modelLibraryReconstructionEntity.getClassifierBehaviorMetaClassInstance();
                boolean isReplaceClassifierBehavior = modelLibraryClassifierBehaviorMetaClassInstance != null &&
                        modelLibraryReconstructionEntity.getNestedClassifierMetaClassInstances().stream().noneMatch(e -> Objects.equals(e.getId(), modelLibraryClassifierBehaviorMetaClassInstance.getId()));

                List<ModelPropertyRefactoringResult> classifierBehaviorModelPropertyRefactoringResults = new ArrayList<>();
                if (isReplaceClassifierBehavior) {
                    String modelLibraryClassifierBehaviorMetaClassInstanceId = modelLibraryClassifierBehaviorMetaClassInstance.getId();

                    //保留结构与定义的场景下，处理可能存在的同名问题
                    List<UpdateModelDTO> updateModelDTOS = new ArrayList<>();
                    if (Objects.equals(batchRefactoringModelDTO.getReuseStrategy(), RefactoringModelReuseStrategy.RETAIN_STRUCTURAL_DEFINITION.getCode())) {
                        List<String> givenTypes = modelLibraryReconstructionEntity.getInstanceIdGivenTypesMap().
                                get(modelLibraryClassifierBehaviorMetaClassInstanceId).stream().sorted().collect(Collectors.toList());
                        String name = modelLibraryModelPropertyInfoMap.get(modelLibraryClassifierBehaviorMetaClassInstanceId).queryStringValue(UMLDefinitionConstants.NamedElement_name);

                        Set<String> namesSet = givenTypesNamesMap.getOrDefault(givenTypes, new HashSet<>());
                        String newName = name;
                        if (namesSet.contains(name)) {
                            newName = getNewName(name, namesSet);
                        }
                        namesSet.add(newName);
                        givenTypesNamesMap.put(givenTypes, namesSet);
                        if (!Objects.equals(name, newName)) {
                            UpdateModelDTO nameUpdateModelDTO = UpdateModelFactory.newInstance(projectId, modelLibraryClassifierBehaviorMetaClassInstanceId, UMLDefinitionConstants.NamedElement_name, newName);
                            updateModelDTOS.add(nameUpdateModelDTO);
                        }
                    }
                    ModelPropertyRefactoringResult addClassifierBehavior = ModelPropertyRefactoringResult.builder().
                            projectId(modelLibraryProjectId).
                            metaClassInstance(modelLibraryClassifierBehaviorMetaClassInstance).
                            metaClassInstanceId(modelLibraryClassifierBehaviorMetaClassInstanceId).
                            operation(ModelPropertyOperationEnum.ADD).
                            updateModelDTOS(updateModelDTOS).build();
                    classifierBehaviorModelPropertyRefactoringResults.add(addClassifierBehavior);
                }

                metaInstanceRefactoringResult.setPortModelPropertyRefactoringResults(portModelPropertyRefactoringResults);
                metaInstanceRefactoringResult.setPartConstraintModelPropertyRefactoringResults(partConstraintModelPropertyRefactoringResults);
                metaInstanceRefactoringResult.setNestedClassifierModelPropertyRefactoringResults(nestedClassifierModelPropertyRefactoringResults);
                metaInstanceRefactoringResult.setOtherModelPropertyRefactoringResults(otherModelPropertyRefactoringResults);
                metaInstanceRefactoringResult.setClassifierBehaviorModelPropertyRefactoringResults(classifierBehaviorModelPropertyRefactoringResults);
                results.add(metaInstanceRefactoringResult);
            }
        }
        return results;
    }


    private List<UpdateModelDTO> getAffectedAttributesUpdateModelDTOS(Map<String, Map<String, Set<String>>> affectedInstanceAttributesMap,
                                                                      Map<String, MetaClassInstance> replaceMetaInstanceMap, String projectId) {
        if (MapUtils.isEmpty(affectedInstanceAttributesMap)) {
            return Collections.emptyList();
        }
        List<UpdateModelDTO> updateModelDTOS = new ArrayList<>();

        for (Map.Entry<String, Map<String, Set<String>>> entry : affectedInstanceAttributesMap.entrySet()) {
            String instanceId = entry.getKey();
            MetaClassInstance metaClassInstance = internalUmlService.fetchInstance(instanceId, projectId);
            if (Objects.isNull(metaClassInstance)) {
                continue;
            }
            Map<String, MofPropertyInfo> mofPropertyInfoMap = internalUmlService.queryPropertyByKeys(projectId, metaClassInstance, new ArrayList<>(entry.getValue().keySet()));

            Map<String, Set<String>> propertyKeyAffectedValueMap = entry.getValue();
            for (Map.Entry<String, Set<String>> propertyKeyAffectedValueEntry : propertyKeyAffectedValueMap.entrySet()) {
                String affectedPropertyKey = propertyKeyAffectedValueEntry.getKey();
                Set<String> affectedPropertyValueInstanceIds = propertyKeyAffectedValueEntry.getValue();

                if (!mofPropertyInfoMap.containsKey(affectedPropertyKey)) {
                    continue;
                }
                Object values = mofPropertyInfoMap.get(affectedPropertyKey).getValues();
                Object newValues;
                if (values instanceof List) {
                    newValues = ((List<MetaClassInstance>) values).stream().map(e -> {
                        if (affectedPropertyValueInstanceIds.contains(e.getId())) {
                            return replaceMetaInstanceMap.get(e.getId());
                        }
                        return e;
                    }).filter(Objects::nonNull).collect(Collectors.toList());
                } else {
                    MetaClassInstance temp = (MetaClassInstance) values;
                    newValues = replaceMetaInstanceMap.get(temp.getId());
                }
                if (Objects.nonNull(newValues)) {
                    UpdateModelDTO updateModelDTO = UpdateModelFactory.newInstance(projectId, metaClassInstance.getId(), affectedPropertyKey, newValues);
                    updateModelDTOS.add(updateModelDTO);
                }

            }
        }
        return updateModelDTOS;
    }


    private List<ModelPropertyRefactoringResult> getModelPropertyRefactoringResults(ModelRefactoringDataHolder
                                                                                            modelRefactoringDataHolder, Map<List<String>, Set<String>> givenTypesNamesMap) {
        Map<List<String>, List<String>> givenTypesGroupedInstanceIdsMap = modelRefactoringDataHolder.getGivenTypesGroupedInstanceIdsMap();
        Map<String, ModelPropertyInfo> modelPropertyInfoMap = modelRefactoringDataHolder.getModelPropertyInfoMap();
        Map<List<String>, List<String>> modelLibraryGivenTypesGroupedInstanceIdsMap = modelRefactoringDataHolder.getModelLibraryGivenTypesGroupedInstanceIdsMap();
        Map<String, ModelPropertyInfo> modelLibraryModelPropertyInfoMap = modelRefactoringDataHolder.getModelLibraryModelPropertyInfoMap();
        int namingStrategy = modelRefactoringDataHolder.getDuplicateNameHandlingStrategy();
        String projectId = modelRefactoringDataHolder.getProjectId();
        String modelLibraryProjectId = modelRefactoringDataHolder.getModelLibraryProjectId();

        Map<List<String>, List<String>> intersectionGivenTypesGroupedInstanceIdsMap = givenTypesGroupedInstanceIdsMap.entrySet().stream().filter(e -> modelLibraryGivenTypesGroupedInstanceIdsMap.containsKey(e.getKey())).
                collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (k1, k2) -> k1));

        Map<List<String>, List<String>> exclusiveModelLibraryGivenTypesGroupedInstanceIdsMap = modelLibraryGivenTypesGroupedInstanceIdsMap.entrySet().stream().filter(e -> !givenTypesGroupedInstanceIdsMap.containsKey(e.getKey())).
                collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (k1, k2) -> k1));

        List<ModelPropertyRefactoringResult> results = new ArrayList<>();

        Set<String> needDeleteInstanceIds = new HashSet<>();

        //项目与模型库存在同类型模型的模型处理
        intersectionGivenTypesGroupedInstanceIdsMap.forEach((givenTypes, tempInstanceIds) -> {

            Map<String, String> namesInstanceIdMap = tempInstanceIds.stream().collect(Collectors.toMap(tempInstanceId -> modelPropertyInfoMap.get(tempInstanceId).
                    queryStringValue(UMLDefinitionConstants.NamedElement_name), Function.identity(), (k1, k2) -> k1));

            List<String> modelLibraryInstanceIds = modelLibraryGivenTypesGroupedInstanceIdsMap.getOrDefault(givenTypes, Collections.emptyList());
            Map<String, String> modelLibraryNamesInstanceIdMap = modelLibraryInstanceIds.stream().collect(Collectors.toMap(tempInstanceId -> modelLibraryModelPropertyInfoMap.get(tempInstanceId).
                    queryStringValue(UMLDefinitionConstants.NamedElement_name), Function.identity(), (k1, k2) -> k1));

            Map<String, String> modelLibraryNotDumplicateNameInstanceIdMap = modelLibraryNamesInstanceIdMap.entrySet().stream().filter(e -> !namesInstanceIdMap.containsKey(e.getKey())).
                    collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (k1, k2) -> k2));

            Map<String, String> modelLibraryDumplicateNameInstanceIdMap = modelLibraryNamesInstanceIdMap.entrySet().stream().filter(e -> namesInstanceIdMap.containsKey(e.getKey())).
                    collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (k1, k2) -> k2));
            namesInstanceIdMap.putAll(modelLibraryNotDumplicateNameInstanceIdMap);

            //重名保留模型库模型策略
            if (Objects.equals(namingStrategy, DuplicateNameHandlingEnum.KEEP_LIBRARY_MODEL.getCode())) {
                List<ModelPropertyRefactoringResult> duplicateNameModelPropertyRefactoringResults = new ArrayList<>();
                modelLibraryDumplicateNameInstanceIdMap.forEach((libraryInstanceName, libraryInstanceId) -> {
                    String replaceInstanceId = namesInstanceIdMap.get(libraryInstanceName);
                    needDeleteInstanceIds.add(replaceInstanceId);

                    //查询项目属性值里面，存在指向被替换模型的属性值，等待后续更新
                    List<EncapsulationService.ReferenceInfo> referenceInfo = encapsulationService.getReferenceInfo(projectId, replaceInstanceId);

                    MetaClassInstance typedTypeMetaClassInstance = modelPropertyInfoMap.get(replaceInstanceId).queryInstanceValue(UMLDefinitionConstants.TypedElement_type);
                    List<UpdateModelDTO> updateModelDTOS = new ArrayList<>();
                    if (typedTypeMetaClassInstance != null) {
                        UpdateModelDTO typeUpdateModelDTO = UpdateModelFactory.newInstance(projectId, libraryInstanceId, UMLDefinitionConstants.TypedElement_type, typedTypeMetaClassInstance);
                        updateModelDTOS.add(typeUpdateModelDTO);
                    }

                    ModelPropertyRefactoringResult duplicateNameModelPropertyRefactoringResult = ModelPropertyRefactoringResult.builder().
                            projectId(modelLibraryProjectId).
                            metaClassInstanceId(libraryInstanceId).
                            metaClassInstance(modelLibraryModelPropertyInfoMap.get(libraryInstanceId).getInstance()).
                            replaceMetaClassInstanceId(replaceInstanceId).
                            replaceMetaClassInstance(modelPropertyInfoMap.get(replaceInstanceId).getInstance()).
                            affectedAttributes(referenceInfo).
                            operation(ModelPropertyOperationEnum.REPLACE).
                            updateModelDTOS(updateModelDTOS).build();
                    duplicateNameModelPropertyRefactoringResults.add(duplicateNameModelPropertyRefactoringResult);
                });

                results.addAll(duplicateNameModelPropertyRefactoringResults);
            }
            //重名保留项目与模型库两者模型策略
            if (Objects.equals(namingStrategy, DuplicateNameHandlingEnum.KEEP_DOUBLE_MODEL.getCode())) {
                Set<String> givenTypesNamesSet = givenTypesNamesMap.getOrDefault(givenTypes, new HashSet<>());
                givenTypesNamesSet.addAll(modelLibraryNotDumplicateNameInstanceIdMap.keySet());

                List<ModelPropertyRefactoringResult> duplicateNameModelPropertyRefactoringResults = new ArrayList<>();
                modelLibraryDumplicateNameInstanceIdMap.forEach((libraryInstanceName, libraryInstanceId) -> {
                    String newName = getNewName(libraryInstanceName, givenTypesNamesSet);
                    givenTypesNamesSet.add(newName);
                    UpdateModelDTO nameUpdateModelDTO = UpdateModelFactory.newInstance(projectId, libraryInstanceId, UMLDefinitionConstants.NamedElement_name, newName);

                    ModelPropertyRefactoringResult duplicateNameModelPropertyRefactoringResult = ModelPropertyRefactoringResult.builder().
                            projectId(modelLibraryProjectId).
                            operation(ModelPropertyOperationEnum.ADD).
                            metaClassInstanceId(libraryInstanceId).
                            metaClassInstance(modelLibraryModelPropertyInfoMap.get(libraryInstanceId).getInstance()).
                            updateModelDTOS(Collections.singletonList(nameUpdateModelDTO)).build();
                    duplicateNameModelPropertyRefactoringResults.add(duplicateNameModelPropertyRefactoringResult);
                });
                givenTypesNamesMap.put(givenTypes, givenTypesNamesSet);
                results.addAll(duplicateNameModelPropertyRefactoringResults);
            }

            //模型库中非重名模型处理
            List<ModelPropertyRefactoringResult> notDuplicateNameModelPropertyRefactoringResults = modelLibraryNotDumplicateNameInstanceIdMap.values().stream().map(e -> ModelPropertyRefactoringResult.builder().
                    operation(ModelPropertyOperationEnum.ADD).
                    projectId(modelLibraryProjectId).
                    metaClassInstance(modelLibraryModelPropertyInfoMap.get(e).getInstance()).
                    metaClassInstanceId(e).
                    updateModelDTOS(Collections.emptyList()).
                    build()).collect(Collectors.toList());
            results.addAll(notDuplicateNameModelPropertyRefactoringResults);

        });
        //所有模型库独有的子一级模型全部走复制操作
        List<ModelPropertyRefactoringResult> exclusiveModelPropertyRefactoringResults = exclusiveModelLibraryGivenTypesGroupedInstanceIdsMap.values().stream().
                flatMap(Collection::parallelStream).map(e -> ModelPropertyRefactoringResult.builder().
                operation(ModelPropertyOperationEnum.ADD).
                projectId(modelLibraryProjectId).
                metaClassInstance(modelLibraryModelPropertyInfoMap.get(e).getInstance()).
                metaClassInstanceId(e).
                updateModelDTOS(Collections.emptyList()).
                build()).collect(Collectors.toList());
        results.addAll(exclusiveModelPropertyRefactoringResults);

        //对替换的子一级元素进行删除
        List<ModelPropertyRefactoringResult> deleteModelPropertyRefactoringResults = needDeleteInstanceIds.stream().map(e -> ModelPropertyRefactoringResult.builder().
                operation(ModelPropertyOperationEnum.DELETE).
                projectId(projectId).
                metaClassInstanceId(e).
                updateModelDTOS(Collections.emptyList()).
                build()
        ).collect(Collectors.toList());


        results.addAll(deleteModelPropertyRefactoringResults);

        return results;
    }

    private static String getNewName(String libraryInstanceName, Set<String> givenTypesNamesSet) {
        int i = 1;
        String newName = libraryInstanceName + i;
        while (givenTypesNamesSet.contains(newName)) {
            i++;
            newName = libraryInstanceName + i;
        }
        return newName;
    }


    private Map<List<String>, List<String>> getGivenTypesGroupedInstanceIdsMap
            (Map<String, Set<String>> instanceIdGivenTypesMap, List<MetaClassInstance> portMetaClassInstances) {
        Set<String> instanceIdsSet = portMetaClassInstances.stream().map(MetaClassInstance::getId).collect(Collectors.toSet());
        return instanceIdGivenTypesMap.entrySet().stream().filter(e -> instanceIdsSet.contains(e.getKey())).
                collect(Collectors.groupingBy(e -> e.getValue().stream().sorted().collect(Collectors.toList()), Collectors.mapping(Map.Entry::getKey, Collectors.toList())));
    }

    /**
     * 将需要的信息封装
     *
     * @param projectId
     * @param instanceIds
     * @return
     */
    private Map<String, ReconstructionEntity> createReconstructionEntitiesMap(String projectId, List<String> instanceIds) {
        DataSourceRepository.setCurrentStoreId(projectId);

        List<MetaClassInstance> metaClassInstances = internalUmlService.fetchInstanceByIds(instanceIds, projectId);
        Map<String, ModelPropertyInfo> modelPropertyInfoMap = getModelPropertyInfoMap(projectId, metaClassInstances, Stream.of(UMLDefinitionConstants.Class_nestedClassifier,
                UMLDefinitionConstants.BehavioredClassifier_classifierBehavior).collect(Collectors.toList()));

        Map<String, List<MetaClassInstance>> nextLevelInstancesMap = metaClassInstances.stream().collect(Collectors.toMap(MetaClassInstance::getId,
                e -> internalUmlService.getChildren(e, false, projectId), (k1, k2) -> k1));

        List<MetaClassInstance> nextLevelInstances = nextLevelInstancesMap.values().stream().flatMap(Collection::parallelStream).collect(Collectors.toList());

        Map<String, Set<String>> nextLevelInstanceIdGivenTypesMap = internalUmlService.getGivenTypes(projectId, nextLevelInstances);


        Map<String, ModelPropertyInfo> nextLevelModelPropertyInfoMap = getModelPropertyInfoMap(projectId, nextLevelInstances, Stream.of(UMLDefinitionConstants.NamedElement_name,
                UMLDefinitionConstants.Element_appliedStereotype,
                UMLDefinitionConstants.TypedElement_type).collect(Collectors.toList()));


        return metaClassInstances.stream().map(metaClassInstance -> {
            List<MetaClassInstance> nextLevelInstancesOfMetaClassInstance = nextLevelInstancesMap.getOrDefault(metaClassInstance.getId(), Collections.emptyList()).
                    stream().filter(e -> !(nextLevelInstanceIdGivenTypesMap.getOrDefault(e.getId(), Collections.emptySet()).contains(UMLDefinitionConstants.InstanceSpecification) &&
                    nextLevelModelPropertyInfoMap.get(e.getId()).queryStringValue(UMLDefinitionConstants.NamedElement_name) == null)).collect(Collectors.toList());


            Map<String, Set<String>> instanceIdGivenTypesMapOfNextLevelInstances = nextLevelInstancesOfMetaClassInstance.stream().filter(e -> nextLevelInstanceIdGivenTypesMap.containsKey(e.getId())).
                    collect(Collectors.toMap(MetaClassInstance::getId, e -> nextLevelInstanceIdGivenTypesMap.get(e.getId()), (k1, k2) -> k1));


            Map<List<String>, Set<String>> givenTypesNamesSet = instanceIdGivenTypesMapOfNextLevelInstances.entrySet().stream().collect(Collectors.groupingBy(e -> e.getValue().stream().sorted().collect(Collectors.toList()),
                    Collectors.mapping(entry -> nextLevelModelPropertyInfoMap.get(entry.getKey()).queryStringValue(UMLDefinitionConstants.NamedElement_name), Collectors.toSet())));


            Map<String, ModelPropertyInfo> modelPropertyInfoMapOfNextLevelInstances = nextLevelInstancesOfMetaClassInstance.stream().filter(e -> nextLevelModelPropertyInfoMap.containsKey(e.getId())).
                    collect(Collectors.toMap(MetaClassInstance::getId, e -> nextLevelModelPropertyInfoMap.get(e.getId()), (k1, k2) -> k1));
            ModelPropertyInfo parentModelPropertyInfo = modelPropertyInfoMap.get(metaClassInstance.getId());

            MetaClassInstance classifierBehaviorMetaClassInstance = parentModelPropertyInfo.queryInstanceValue(UMLDefinitionConstants.BehavioredClassifier_classifierBehavior);

            List<MetaClassInstance> nestedClassifierMetaClassInstances = parentModelPropertyInfo.queryListInstanceValue(UMLDefinitionConstants.Class_nestedClassifier);

            List<MetaClassInstance> portMetaClassInstances = nextLevelInstancesOfMetaClassInstance.stream().filter(e ->
                    instanceIdGivenTypesMapOfNextLevelInstances.getOrDefault(e.getId(), Collections.emptySet()).contains(UMLDefinitionConstants.Port)).collect(Collectors.toList());

            List<MetaClassInstance> partConstraintMetaClassInstances = nextLevelInstancesOfMetaClassInstance.stream().filter(e -> {
                Set<String> givenTypes = instanceIdGivenTypesMapOfNextLevelInstances.getOrDefault(e.getId(), Collections.emptySet());
                return givenTypes.contains(UMLDefinitionConstants.Customization_PartProperty) ||
                        givenTypes.contains(UMLDefinitionConstants.Customization_ConstraintProperty);
            }).collect(Collectors.toList());

            Set<String> metaClassInstanceIdsSet = Stream.concat(Stream.concat(portMetaClassInstances.stream(), partConstraintMetaClassInstances.stream()),
                    nestedClassifierMetaClassInstances.stream()).map(MetaClassInstance::getId).collect(Collectors.toSet());
            if (classifierBehaviorMetaClassInstance != null) {
                metaClassInstanceIdsSet.add(classifierBehaviorMetaClassInstance.getId());
            }

            List<MetaClassInstance> otherMetaClassInstances = nextLevelInstancesOfMetaClassInstance.stream().filter(e -> !metaClassInstanceIdsSet.contains(e.getId())).collect(Collectors.toList());


            return ReconstructionEntity.builder().
                    projectId(projectId).
                    parentMetaClassInstance(metaClassInstance).
                    parentModelInfo(parentModelPropertyInfo).
                    classifierBehaviorMetaClassInstance(classifierBehaviorMetaClassInstance).
                    nestedClassifierMetaClassInstances(nestedClassifierMetaClassInstances).
                    portMetaClassInstances(portMetaClassInstances).
                    partConstraintMetaClassInstances(partConstraintMetaClassInstances).
                    otherMetaClassInstances(otherMetaClassInstances).
                    metaClassInstances(nextLevelInstancesOfMetaClassInstance).
                    instanceIdGivenTypesMap(instanceIdGivenTypesMapOfNextLevelInstances).
                    modelPropertyInfoMap(modelPropertyInfoMapOfNextLevelInstances).
                    givenTypesNamesMap(givenTypesNamesSet).
                    build();
        }).collect(Collectors.toMap(e -> e.getParentMetaClassInstance().getId(), Function.identity(), (k1, k2) -> k1));


    }


    private Map<String, ModelPropertyInfo> getModelPropertyInfoMap(String
                                                                           projectId, List<MetaClassInstance> nextLevelInstances, List<String> propertyKeys) {
        return modelPropertyInfoService.createModelPropertyInfoMap(projectId, nextLevelInstances, propertyKeys);
    }


    /**
     * 转换成批量重构对象
     *
     * @param refactoringModelDTO
     * @return
     */
    private static BatchRefactoringModelDTO transferToBatchRefactoringModelDTO(RefactoringModelDTO refactoringModelDTO) {
        BatchRefactoringModelDTO batchRefactoringModelDTO = new BatchRefactoringModelDTO();
        batchRefactoringModelDTO.setProjectId(refactoringModelDTO.getProjectId());
        batchRefactoringModelDTO.setReuseStrategy(refactoringModelDTO.getReuseStrategy());
        batchRefactoringModelDTO.setNamingStrategy(refactoringModelDTO.getNamingStrategy());
        batchRefactoringModelDTO.setClassifierBehaviorStrategy(refactoringModelDTO.getClassifierBehaviorStrategy());
        ModelMappingInfo modelMappingInfo = new ModelMappingInfo();
        modelMappingInfo.setInstanceId(refactoringModelDTO.getInstanceId());
        modelMappingInfo.setModelLibraryInstanceId(refactoringModelDTO.getModelLibraryInstanceId());
        Map<String, List<ModelMappingInfo>> modelInfosMap = Collections.singletonMap(refactoringModelDTO.getModelLibraryProjectId(), Collections.singletonList(modelMappingInfo));
        batchRefactoringModelDTO.setModelMappingInfosMap(modelInfosMap);
        return batchRefactoringModelDTO;
    }


    @NotNull
    public LibraryCreateInstanceVo dragModelLibraryBehaviorToState(DragModelLibraryBehaviorToStateDTO
                                                                           dragModelLibraryBehaviorToStateDTO) {
        String projectId = dragModelLibraryBehaviorToStateDTO.getProjectId();
        String stateInstanceId = dragModelLibraryBehaviorToStateDTO.getStateInstanceId();
        String modelLibraryBehaviorId = dragModelLibraryBehaviorToStateDTO.getModelLibraryBehaviorId();
        MetaClassInstance state = internalUmlService.fetchInstance(stateInstanceId, projectId);
        MetaClassInstance doActivity = internalUmlService.queryInstanceProperty(projectId, state, UMLDefinitionConstants.State_doActivity);
        LibraryCreateInstanceVo libraryCreateInstanceVo = new LibraryCreateInstanceVo();
        LocalTransaction transaction = transactionService.createTransaction(projectId, COPY_MODEL);
        try {
            Map<String, MetaClassInstance> result = umlService.paste(dragModelLibraryBehaviorToStateDTO.getModelLibraryProjectId(),
                    modelLibraryBehaviorId, projectId, stateInstanceId);
            MetaClassInstance behaviorInstance = result.get(modelLibraryBehaviorId);
            if (Objects.isNull(behaviorInstance)) {
                throw AbortExecutionException.build(ErrorCode.ADD_MODEL_ERROR);
            }
            String propertyKey = dragModelLibraryBehaviorToStateDTO.getPropertyKey();

            if (StringUtils.equals(propertyKey, UMLDefinitionConstants.State_entry)
                    || StringUtils.equals(propertyKey, UMLDefinitionConstants.State_exit)) {
                umlService.updateModel(projectId, stateInstanceId, propertyKey, behaviorInstance);
                if (Objects.nonNull(doActivity) && !doActivity.equals(behaviorInstance)) {
                    umlService.updateModel(projectId, stateInstanceId, UMLDefinitionConstants.State_doActivity, doActivity);
                } else {
                    umlService.removeModel(projectId, stateInstanceId, UMLDefinitionConstants.State_doActivity);
                }
            }
            libraryCreateInstanceVo.setInstanceId(behaviorInstance.getId());
            // 填充复制粘贴模型 旧模型->新模型映射
            libraryCreateInstanceVo.setCopyInfoVos(getCopyInfoVo(result));
            transactionService.commit(projectId);
            InstanceVoUtils.fillModelResultVo(libraryCreateInstanceVo, transaction);
        } catch (TransactionNotExistingException | LocalTransactionNotStartException e) {
            throw AbortExecutionException.build(ErrorCode.TRANSACTION_ERROR, e);
        } catch (Exception e) {
            transactionService.rollBack(projectId, transaction);
            throw AbortExecutionException.build(ErrorCode.ADD_MODEL_ERROR, e);
        }
        return libraryCreateInstanceVo;
    }
}
